﻿<%@ WebHandler Language="C#" Class="ApsProduceBalanceHandler" %>

using System;
using System.Web;
using BusinessRule.DTO;
using System.Web.SessionState;
using DatabaseAccess.DBUtility;
using System.Data.OracleClient;
using System.Data;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
using Newtonsoft.Json;
using BusinessRule.Business;
using BusinessRule.IBusiness;
using BusinessRule.BusinessFactory;

//Description:排产生产作业平衡处理程序
//Copyright (c) : 通力凯顿（北京）系统集成有限公司
//Writer:longb
//create Date:2023-09-04

public class ApsProduceBalanceHandler : IHttpHandler, IRequiresSessionState
{
    CurrentUserInfo m_UserInfo;
    private LimitedCapacityBusiness m_LMObj = new LimitedCapacityBusiness();
    WorkFlowStepMaintBusiness workFlowStepMaint = new WorkFlowStepMaintBusiness();
    public void ProcessRequest(HttpContext context)
    {
        try
        {
            var action = context.Request["action"].ToString();
            m_UserInfo = (CurrentUserInfo)context.Session["CurrentUserInfo"];
            switch (action)
            {
                case "InitPageData": //获取页面初始化数据
                    InitPageData(context);
                    break;
                case "getApsProduceBalanceData": //查询生产作业平衡排产数据
                    getApsProduceBalanceData(context);
                    break;
                case "getContainerSpecApsData"://工序排产信息
                    getContainerSpecApsData(context);
                    break;
                case "getApsResourceData":
                    getApsResourceData(context);
                    break;
                case "getApsResourceFHData":
                    getApsResourceFHData(context);
                    break;
                case "GetStepLimitedAps"://设备日排产数据
                    GetStepLimitedAps(context);
                    break;
                case "SaveStepResourceData":
                    SaveStepResourceData(context);
                    break;
                case "UpdateResourceData"://更新设备（能力、日历、班次）信息
                    UpdateResourceData(context);
                    break;
                case "ExportResDetailExcle"://导出设备能力明细 add by zhangrj 20231026
                    ExportResDetailExcle(context);
                    break;
                /*-----------------生产作业平衡（预排相关）
                 * 仅复制上面的相同方法并改其名，将其中所有的排产数据改为预排数据
                 * add by zhangrj 20241218----------------------------*/
                case "getPreApsProduceBalanceData": //查询生产作业平衡排产数据
                    getPreApsProduceBalanceData(context);
                    break;
                case "getContainerSpecPreApsData"://工序排产信息
                    getContainerSpecPreApsData(context);
                    break;
                case "getPreApsResourceData":
                    getPreApsResourceData(context);
                    break;
                case "getPreApsResourceFHData":
                    getPreApsResourceFHData(context);
                    break;
                case "GetStepLimitedPreAps"://设备日排产数据
                    GetStepLimitedPreAps(context);
                    break;
                case "SaveStepResourcePreData":
                    SaveStepResourcePreData(context);
                    break;
                case "ExportPreResDetailExcle"://导出设备能力明细
                    ExportPreResDetailExcle(context);
                    break;
                default:
                    break;
            }
        }
        catch (Exception ex)
        {
            var result = new uMESProcessResult();
            result.Result = false;
            result.Message = ex.Message;
            context.Response.ContentType = "text/html";
            context.Response.Write(JsonConvert.SerializeObject(result));
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    /// <summary>
    /// 导出设备能力明细 add by zhangrj 20231026
    /// </summary>
    /// <param name="context"></param>
    public void ExportResDetailExcle(HttpContext context)
    {
        DataTable dtExport = new DataTable();
        dtExport.Columns.Add("设备编号");
        dtExport.Columns.Add("设备名");
        dtExport.Columns.Add("时间");
        dtExport.Columns.Add("班次");
        dtExport.Columns.Add("可用能力");
        dtExport.Columns.Add("需求能力");
        dtExport.Columns.Add("能力负荷");
        dtExport.Columns.Add("能力单位");
        string date = context.Request["date"].ToString();
        //查询分厂下所有设备
        string sql = string.Format(@"SELECT r.resourcename,r.description,r.resourceid,w.workshiftname,w.workshiftid
                                    FROM resourcedef r 
                                    LEFT JOIN Workshift w ON w.workshiftid = r.workshiftid AND w.isuse = 0
                                    WHERE r.factoryid = '{0}'", m_UserInfo.FactoryID);
        DataTable dtRes = DatabaseHelper.Query_ReturnDatTable(sql);
        foreach (DataRow item in dtRes.Rows)
        {
            sql = string.Format(@"SELECT round(nvl(SUM(MINS),0)/60,2) hours FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID='{0}'", item["workshiftid"].ToString());
            DataTable dtTotalTime = DatabaseHelper.Query_ReturnDatTable(sql);
            Dictionary<string, object> para = GetApsResourceFHData(item["resourceid"].ToString(), date);
            int monthDay = Convert.ToInt32(para["days"]);
            ArrayList scdata = (ArrayList)para["scdata"];
            ArrayList xzdata = (ArrayList)para["xzdata"];
            ArrayList fhdata = (ArrayList)para["fhdata"];
            for (int i = 0; i < monthDay; i++)
            {
                DataRow dr = dtExport.NewRow();
                dr["设备编号"] = item["resourcename"].ToString();
                dr["设备名"] = item["description"].ToString();
                dr["时间"] = (i + 1).ToString() + "日";
                dr["班次"] = item["workshiftname"].ToString();
                dr["可用能力"] = dtTotalTime.Rows.Count > 0 ? dtTotalTime.Rows[0]["hours"].ToString() : "";
                dr["需求能力"] = string.IsNullOrWhiteSpace(scdata[i].ToString()) ? "0" : scdata[i].ToString();
                dr["能力负荷"] = "";
                dr["能力单位"] = "";
                dtExport.Rows.Add(dr);
            }
        }
        byte[] bytes = uLMS_CommonFunction.DataTableExportToExcel(dtExport, string.Format("设备能力明细{0}", date.ToString()));
        context.Response.Clear();
        context.Response.Buffer = true;
        context.Response.ClearHeaders();
        context.Response.ClearContent();
        context.Response.ContentType = "application/vnd.ms-excel";
        context.Response.AddHeader("fileDownload", "1");
        context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}{1}.xls", context.Server.UrlEncode("设备能力明细记录"), DateTime.Now.ToString("yyyyMMddHHmmssffff")));
        context.Response.AddHeader("Content-Length", bytes.Length.ToString());
        context.Response.AddHeader("Content-Type", "UTF-8");
        context.Response.Charset = "UTF-8";
        context.Response.ContentEncoding = System.Text.Encoding.UTF8;
        context.Response.BinaryWrite(bytes);
        context.Response.Flush();
        context.Response.Close();
    }

    /// <summary>
    /// 导出设备能力明细（预排） add by zhangrj 20241218
    /// </summary>
    /// <param name="context"></param>
    public void ExportPreResDetailExcle(HttpContext context)
    {
        DataTable dtExport = new DataTable();
        dtExport.Columns.Add("设备编号");
        dtExport.Columns.Add("设备名");
        dtExport.Columns.Add("时间");
        dtExport.Columns.Add("班次");
        dtExport.Columns.Add("可用能力");
        dtExport.Columns.Add("需求能力");
        dtExport.Columns.Add("能力负荷");
        dtExport.Columns.Add("能力单位");
        //string date = context.Request["date"].ToString();
        string balanceStartDate = context.Request["balanceStartDate"].ToString();
        string balanceEndDate = context.Request["balanceEndDate"].ToString();
        //查询分厂下所有设备
        string sql = string.Format(@"SELECT r.resourcename,r.description,r.resourceid,w.workshiftname,w.workshiftid
                                    FROM resourcedef r 
                                    LEFT JOIN Workshift w ON w.workshiftid = r.workshiftid AND w.isuse = 0
                                    WHERE r.factoryid = '{0}'", m_UserInfo.FactoryID);
        DataTable dtRes = DatabaseHelper.Query_ReturnDatTable(sql);
        foreach (DataRow item in dtRes.Rows)
        {
            sql = string.Format(@"SELECT round(nvl(SUM(MINS),0)/60,2) hours FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID='{0}'", item["workshiftid"].ToString());
            DataTable dtTotalTime = DatabaseHelper.Query_ReturnDatTable(sql);
            Dictionary<string, object> para = getPreApsResourceFHData(item["resourceid"].ToString(),balanceStartDate,balanceEndDate);
            int monthDay = Convert.ToInt32(para["days"]);
            ArrayList scdata = (ArrayList)para["scdata"];
            ArrayList xzdata = (ArrayList)para["xzdata"];
            ArrayList fhdata = (ArrayList)para["fhdata"];
            for (int i = 0; i < monthDay; i++)
            {
                DataRow dr = dtExport.NewRow();
                dr["设备编号"] = item["resourcename"].ToString();
                dr["设备名"] = item["description"].ToString();
                dr["时间"] = Convert.ToDateTime(balanceStartDate).AddDays(i).ToString("yyyy-MM-dd") + "日";
                dr["班次"] = item["workshiftname"].ToString();
                dr["可用能力"] = dtTotalTime.Rows.Count > 0 ? dtTotalTime.Rows[0]["hours"].ToString() : "";
                dr["需求能力"] = string.IsNullOrWhiteSpace(scdata[i].ToString()) ? "0" : scdata[i].ToString();
                dr["能力负荷"] = "";
                dr["能力单位"] = "";
                dtExport.Rows.Add(dr);
            }
        }
        byte[] bytes = uLMS_CommonFunction.DataTableExportToExcel(dtExport, string.Format("设备能力明细{0}", balanceStartDate.ToString() + "至" + balanceEndDate));
        context.Response.Clear();
        context.Response.Buffer = true;
        context.Response.ClearHeaders();
        context.Response.ClearContent();
        context.Response.ContentType = "application/vnd.ms-excel";
        context.Response.AddHeader("fileDownload", "1");
        context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}{1}.xls", context.Server.UrlEncode("设备能力明细记录"), DateTime.Now.ToString("yyyyMMddHHmmssffff")));
        context.Response.AddHeader("Content-Length", bytes.Length.ToString());
        context.Response.AddHeader("Content-Type", "UTF-8");
        context.Response.Charset = "UTF-8";
        context.Response.ContentEncoding = System.Text.Encoding.UTF8;
        context.Response.BinaryWrite(bytes);
        context.Response.Flush();
        context.Response.Close();
    }

    public void InitPageData(HttpContext context)
    {
        Dictionary<string, string> para = new Dictionary<string, string>();
        para["FactoryID"] = m_UserInfo.FactoryID.ToString();
        uLMSCommonBusiness commonBusiness = new uLMSCommonBusiness();
        DataTable dt = commonBusiness.GetWorkCenterByFacoryID(m_UserInfo.FactoryID.ToString(), false);
        context.Response.Write(JsonConvert.SerializeObject(dt));
    }

    public void getApsProduceBalanceData(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult();
        Dictionary<string, string> para = JsonConvert.DeserializeObject<Dictionary<string, string>>(context.Request.Form["data"].ToString());

        //var selectSQl = strSql;
        if (!string.IsNullOrWhiteSpace(para["containerName"]))
        {
            strSql += String.Format(" and cci.ContainerName like '%{0}%' ", para["containerName"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["productName"].ToString()))
        {
            strSql += String.Format(" and cci.ProductName like '%{0}%' ", para["productName"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["IsAps"].ToString()))//不为全部时 查询已派或者未派
        {
            if (para["IsAps"].ToString().Equals("1"))
            {
                strSql += " AND EXISTS  (SELECT 1 FROM APSPLANINFO ai WHERE ai.CONTAINERID=cci.containerid AND ai.isuse=0) ";
            }
            else
            {
                strSql += " AND not EXISTS  (SELECT 1 FROM APSPLANINFO ai WHERE ai.CONTAINERID=cci.containerid AND ai.isuse=0) ";
            }
        }

        if (!string.IsNullOrWhiteSpace(para["mfgorderName"].ToString()))
        {
            strSql += String.Format(" and cci.MfgorderName like '%{0}%' ", para["mfgorderName"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(para["poolId"].ToString()))//排产池
        {
            strSql += String.Format(" and cci.WORKCENTERID ='{0}' ", para["poolId"].ToString());

        }
        if (!string.IsNullOrWhiteSpace(para["orderBStartDate"].ToString()))
        {
            strSql += String.Format(" and M.plannedstartdate >= to_date('{0}','YYYY-MM-DD') ", para["orderBStartDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["orderBEndDate"].ToString()))
        {
            strSql += String.Format(" and M.plannedstartdate <= to_date('{0}','YYYY-MM-DD') ", para["orderBEndDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["orderEStartDate"].ToString()))
        {
            strSql += String.Format(" and M.plannedcompletiondate >= to_date('{0}','YYYY-MM-DD') ", para["orderEStartDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["orderEEndDate"].ToString()))
        {
            strSql += String.Format(" and M.plannedcompletiondate <= to_date('{0}','YYYY-MM-DD') ", para["orderEEndDate"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(para["workflowStepName"].ToString()))
        {
            strSql += String.Format(" and cci.WORKFLOWSTEPNAME like '%{0}%' ", para["workflowStepName"].ToString());
        }
        if (m_UserInfo != null)
        {
            strSql += String.Format(" and cci.OriginalFactoryID = '{0}' ", m_UserInfo.FactoryID.ToString());
        }

        strSql += " order by ApsSequence asc, pc.prioritycodename ";
        var paraPage = new uMESPagingDataDTO();
        paraPage.CurrentPageIndex = Convert.ToInt32(context.Request.Form["pageNumber"].ToString());
        paraPage.PageSize = Convert.ToInt32(context.Request.Form["pageSize"].ToString());
        paraPage.strSQL = strSql;
        result = DatabaseHelper.RunProcedureForPage(paraPage);
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 查询生产作业平衡排产数据（预排相关）
    /// </summary>
    /// <param name="context"></param>
    public void getPreApsProduceBalanceData(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult();
        Dictionary<string, string> para = JsonConvert.DeserializeObject<Dictionary<string, string>>(context.Request.Form["data"].ToString());

        //var selectSQl = strSql;
        if (!string.IsNullOrWhiteSpace(para["containerName"]))
        {
            strPreSql += String.Format(" and cci.ContainerName like '%{0}%' ", para["containerName"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["productName"].ToString()))
        {
            strPreSql += String.Format(" and cci.ProductName like '%{0}%' ", para["productName"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["IsAps"].ToString()))//不为全部时 查询已派或者未派
        {
            if (para["IsAps"].ToString().Equals("1"))
            {
                strPreSql += " AND EXISTS  (SELECT 1 FROM APSPLANINFOPre ai WHERE ai.CONTAINERID=cci.containerid AND ai.isuse=0) ";
            }
            else
            {
                strPreSql += " AND not EXISTS  (SELECT 1 FROM APSPLANINFOPre ai WHERE ai.CONTAINERID=cci.containerid AND ai.isuse=0) ";
            }
        }

        if (!string.IsNullOrWhiteSpace(para["mfgorderName"].ToString()))
        {
            strPreSql += String.Format(" and cci.MfgorderName like '%{0}%' ", para["mfgorderName"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(para["workcenterId"].ToString()))//
        {
            strPreSql += String.Format(" and cci.WORKCENTERID ='{0}' ", para["workcenterId"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(para["teamId"].ToString()))//
        {
            strPreSql += String.Format(" and t.teamId ='{0}' ", para["teamId"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(para["orderBStartDate"].ToString()))
        {
            strPreSql += String.Format(" and M.plannedstartdate >= to_date('{0}','YYYY-MM-DD') ", para["orderBStartDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["orderBEndDate"].ToString()))
        {
            strPreSql += String.Format(" and M.plannedstartdate <= to_date('{0}','YYYY-MM-DD') ", para["orderBEndDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["orderEStartDate"].ToString()))
        {
            strPreSql += String.Format(" and M.plannedcompletiondate >= to_date('{0}','YYYY-MM-DD') ", para["orderEStartDate"].ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["orderEEndDate"].ToString()))
        {
            strPreSql += String.Format(" and M.plannedcompletiondate <= to_date('{0}','YYYY-MM-DD') ", para["orderEEndDate"].ToString());
        }
        if (!string.IsNullOrWhiteSpace(para["workflowStepName"].ToString()))
        {
            strPreSql += String.Format(" and cci.WORKFLOWSTEPNAME like '%{0}%' ", para["workflowStepName"].ToString());
        }
        if (m_UserInfo != null)
        {
            strPreSql += String.Format(" and cci.OriginalFactoryID = '{0}' ", m_UserInfo.FactoryID.ToString());
        }

        if (!string.IsNullOrWhiteSpace(para["isOverdue"].ToString()))//查询是否超期 add by zhangrj 20241219
        {
            if (para["isOverdue"].ToString().Equals("1"))
            {
                strPreSql = string.Format("SELECT * FROM ({0}) where isoverdue = '是'", strPreSql);
            }
            else
            {
                strPreSql = string.Format("SELECT * FROM ({0}) where isoverdue = '否'", strPreSql);
            }
        }

        strPreSql += " order by ApsSequence asc, prioritycodename ";

        var paraPage = new uMESPagingDataDTO();
        paraPage.CurrentPageIndex = Convert.ToInt32(context.Request.Form["pageNumber"].ToString());
        paraPage.PageSize = Convert.ToInt32(context.Request.Form["pageSize"].ToString());
        paraPage.strSQL = strPreSql;
        result = DatabaseHelper.RunProcedureForPage(paraPage);
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    public void getContainerSpecApsData(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult();
        var ContainerID = context.Request.Form["ContainerID"].ToString();
        var WorkflowID = context.Request.Form["WorkflowID"].ToString();
        var strSql = @" select * from (select distinct ai.apsplaninfoid,cci.containername,(SELECT min(STARTTIME) FROM ApsPlanDetail app WHERE app.containerid='{0}' AND app.isuse=0  and exists (select 1 from apsplaninfo api where api.apsplaninfoid=app.apsplaninfoid and api.containerid='{0}' and api.ApsType2=2 and api.ApsType=1)) constarttime,
        (SELECT max(ENDTIME) FROM ApsPlanDetail app WHERE app.containerid='{0}' AND app.isuse=0  and exists (select 1 from apsplaninfo api where api.apsplaninfoid=app.apsplaninfoid and api.containerid='{0}' and api.ApsType2=2 and api.ApsType=1)) conendtime,wfs.workflowstepid,
        ad.apsplandetailid,ad.workflowstepname,to_char(ad.starttime,'yyyy-MM-dd hh24:mi:ss') stepstarttime,to_char(ad.endtime,'yyyy-MM-dd hh24:mi:ss') stependtime,
        r.resourcename, s.specno,nvl(sb_.specname,wfs.workflowstepname)specname, s.factoryid,wfs.controlcode,s.lastCheck,s.isspotcheck,
        wfs.PrepareCycle,wfs.MakeCycle,round(wfs.TransferCycle/60,2) TransferCycle,wfs.ShipCycle,wfs.CommiCycle,'普通工序' spectype,
       CASE WHEN cr.CheckDate IS NOT null THEN '已检验'
        	 WHEN cr.ReportDate IS NOT null THEN '已报工'
        	 WHEN ai.APSPLANINFOID IS NOT NULL THEN decode(ad.Status,'1','已下达','已预排')
        	 ELSE '无' END status
        from  workflowstep wfs
          left join (select * from ApsPlanDetail ap where ap.isuse=0  and exists (select 1 from apsplaninfo api where api.apsplaninfoid=ap.apsplaninfoid and api.containerid='{0}' and api.ApsType2=2 and api.ApsType=1)) ad on ad.workflowstepid=wfs.workflowstepid 
          left join ApsPlanInfo ai on ai.apsplaninfoid=ad.apsplaninfoid AND ai.ApsType2=2 and ai.ApsType=1
          left join containercurrentinfo cci on cci.containerid=ai.containerid
          left join resourcedef r on r.resourceid =ad.resourceid 
          left join specbase sb_ on sb_.specbaseid = wfs.specbaseid
          left join spec s on s.specid = nvl(sb_.revofrcdid,wfs.specid)
          left join (select max(reportdate) reportdate,max(checkdate)checkdate,containerid,workflowstepid from containersteprecord where containerid='{0}' group by containerid,workflowstepid)  cr on cr.containerid =ai.containerid and cr.workflowstepid=wfs.workflowstepid
          where 1=1  
          and wfs.workflowid='{1}' )order by workflowstepid";
        DataTable dt = DatabaseHelper.Query_ReturnDatTable(string.Format(strSql, ContainerID, WorkflowID));
        var common = new uLMSCommonBusiness();
        var strWorkflowFactory = m_UserInfo.FactoryID;
        DataTable dtWorkflow = common.GetWorkflowInfoByID(WorkflowID).DBTable;
        if (dtWorkflow.Rows.Count > 0)
        {
            if (!string.IsNullOrWhiteSpace(dtWorkflow.Rows[0]["factoryid"].ToString()))
            {
                strWorkflowFactory = dtWorkflow.Rows[0]["factoryid"].ToString();// '获取工艺workflow上的工厂
            }
        }
        foreach (DataRow row in dt.Rows)
        {
            if (row["controlcode"].ToString().Equals("LY05")) { row["spectype"] = "固定外委"; }
            else if (row["controlcode"].ToString().Equals("LY07")) { row["spectype"] = "虚拟工序"; }
            else if (!row["factoryid"].ToString().Equals(strWorkflowFactory))
            {
                row["spectype"] = row["factoryid"].ToString() == "" ? "工序未维护分厂" : "固定转工";
            }
            if (row["lastCheck"].ToString().Equals("1")) { row["spectype"] = row["spectype"] + "|检序"; }
            if (row["isspotcheck"].ToString().Equals("1")) { row["spectype"] = row["spectype"] + "|特殊"; }

        }

        result.DBTable = dt;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 获取工序的排产数据（预排）
    /// </summary>
    /// <param name="context"></param>
    public void getContainerSpecPreApsData(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult();
        var ContainerID = context.Request.Form["ContainerID"].ToString();
        var WorkflowID = context.Request.Form["WorkflowID"].ToString();
        var strSql = @" select * from (select distinct ai.apsplaninfoid,cci.containername,(SELECT min(STARTTIME) FROM ApsPlanDetail app WHERE app.containerid='{0}' AND app.isuse=0  and exists (select 1 from apsplaninfo api where api.apsplaninfoid=app.apsplaninfoid and api.containerid='{0}' and api.ApsType2=2 and api.ApsType=1)) constarttime,
        (SELECT max(ENDTIME) FROM ApsPlanDetail app WHERE app.containerid='{0}' AND app.isuse=0  and exists (select 1 from apsplaninfo api where api.apsplaninfoid=app.apsplaninfoid and api.containerid='{0}' and api.ApsType2=2 and api.ApsType=1)) conendtime,wfs.workflowstepid,
        ad.apsplandetailid,ad.workflowstepname,to_char(ad.starttime,'yyyy-MM-dd hh24:mi:ss') stepstarttime,to_char(ad.endtime,'yyyy-MM-dd hh24:mi:ss') stependtime,
        r.resourcename, s.specno,nvl(sb_.specname,wfs.workflowstepname)specname, s.factoryid,wfs.controlcode,s.lastCheck,s.isspotcheck,
        wfs.PrepareCycle,wfs.MakeCycle,round(wfs.TransferCycle/60,2) TransferCycle,wfs.ShipCycle,wfs.CommiCycle,'普通工序' spectype,
       CASE WHEN cr.CheckDate IS NOT null THEN '已检验'
        	 WHEN cr.ReportDate IS NOT null THEN '已报工'
        	 WHEN ai.APSPLANINFOID IS NOT NULL THEN decode(ad.Status,'1','已下达','已预排')
        	 ELSE '无' END status
        from  workflowstep wfs
          left join (select * from ApsPlanDetailPre ap where ap.isuse=0  and exists (select 1 from apsplaninfo api where api.apsplaninfoid=ap.apsplaninfoid and api.containerid='{0}' and api.ApsType2=2 and api.ApsType=1)) ad on ad.workflowstepid=wfs.workflowstepid 
          left join ApsPlanInfoPre ai on ai.apsplaninfoid=ad.apsplaninfoid AND ai.ApsType2=2 and ai.ApsType=1
          left join containercurrentinfo cci on cci.containerid=ai.containerid
          left join resourcedef r on r.resourceid =ad.resourceid 
          left join specbase sb_ on sb_.specbaseid = wfs.specbaseid
          left join spec s on s.specid = nvl(sb_.revofrcdid,wfs.specid)
          left join (select max(reportdate) reportdate,max(checkdate)checkdate,containerid,workflowstepid from containersteprecord where containerid='{0}' group by containerid,workflowstepid)  cr on cr.containerid =ai.containerid and cr.workflowstepid=wfs.workflowstepid
          where 1=1  
          and wfs.workflowid='{1}' )order by workflowstepid";
        DataTable dt = DatabaseHelper.Query_ReturnDatTable(string.Format(strSql, ContainerID, WorkflowID));
        var common = new uLMSCommonBusiness();
        var strWorkflowFactory = m_UserInfo.FactoryID;
        DataTable dtWorkflow = common.GetWorkflowInfoByID(WorkflowID).DBTable;
        if (dtWorkflow.Rows.Count > 0)
        {
            if (!string.IsNullOrWhiteSpace(dtWorkflow.Rows[0]["factoryid"].ToString()))
            {
                strWorkflowFactory = dtWorkflow.Rows[0]["factoryid"].ToString();// '获取工艺workflow上的工厂
            }
        }
        foreach (DataRow row in dt.Rows)
        {
            if (row["controlcode"].ToString().Equals("LY05")) { row["spectype"] = "固定外委"; }
            else if (row["controlcode"].ToString().Equals("LY07")) { row["spectype"] = "虚拟工序"; }
            else if (!row["factoryid"].ToString().Equals(strWorkflowFactory))
            {
                row["spectype"] = row["factoryid"].ToString() == "" ? "工序未维护分厂" : "固定转工";
            }
            if (row["lastCheck"].ToString().Equals("1")) { row["spectype"] = row["spectype"] + "|检序"; }
            if (row["isspotcheck"].ToString().Equals("1")) { row["spectype"] = row["spectype"] + "|特殊"; }

        }

        result.DBTable = dt;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 设备月工作总时间=月每天设备占用时间总和
    /// 设备月可用工作总时间=日历工作天数 X 班次每天有效时间
    /// 占用率=设备月工作总时间/设备月可用工作总时间
    /// 335
    /// </summary>
    /// <param name="context"></param>
    private void getApsResourceData(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult();
        Dictionary<string, object> para = JsonConvert.DeserializeObject<Dictionary<string, object>>(context.Request.Form["data"].ToString());
        var resourCode = context.Request.Form["resourCode"].ToString();
        var resourName = context.Request.Form["resourName"].ToString();
        var apspoolID = context.Request.Form["apspoolID"].ToString();
        var balanceMonth = context.Request.Form["balanceMonth"].ToString();
        var isInfinite = context.Request.Form["isInfinite"].ToString();
        var monthDay = DateTime.DaysInMonth(Convert.ToDateTime(balanceMonth + "-01").Year, Convert.ToDateTime(balanceMonth + "-01").Month);
        var CurrentMonthStartDate = Convert.ToDateTime(balanceMonth + "-01").ToString("yyyy-MM-dd HH:mm:ss");
        var NextMonthStartDate = Convert.ToDateTime(balanceMonth + "-01").AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss");
        var strSQL = @"SELECT DISTINCT api.RESOURCEID,r.MAKECALENDARID,r.WORKSHIFTID,nvl(r.DESCRIPTION,' ') RESOURCENAME,r.RESOURCENAME RESOURCENAMECODE,nvl(rf.RESOURCEFAMILYNAME,' ') RESOURCEFAMILYNAME,decode(ISINFINITE,'1','无限',' ')ISINFINITE,nvl(m.MakeCalendarName,' ')MakeCalendarName,nvl(ws.WORKSHIFTNAME,' ') WORKSHIFTNAME,
                (SELECT nvl(COUNT(1),0) empCOUNT FROM  employeeresourcelist esl WHERE esl.RESOURCELISTID=r.RESOURCEID) empCOUNT,
                (SELECT nvl(sum(MINS),0) MINS FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID=r.WORKSHIFTID) MINS,
                round(({0}-(SELECT COUNT(1) holiday FROM MAKECALENDARDETAIL m WHERE to_char(HOLIDAYDATE,'yyyy-MM')='{1}' AND MAKECALENDARID=r.MAKECALENDARID)) 
                *(SELECT nvl(sum(MINS),0) MINS FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID=r.WORKSHIFTID)/60,2) totalmins,0 UseTOTALMINS,0 usetime
                FROM CONTAINERCURRENTINFO c 
                LEFT Join ApsPlanInfo ap ON ap.CONTAINERID=c.CONTAINERID
                LEFT JOIN ApsPlanDetail api ON api.APSPLANINFOID =ap.APSPLANINFOID 
                LEFT JOIN RESOURCEDEF r ON r.RESOURCEID =api.RESOURCEID
                LEFT JOIN ResourceFamily rf ON rf.RESOURCEFAMILYID =r.RESOURCEFAMILYID                  
                LEFT JOIN MakeCalendar m ON m.MAKECALENDARID=r.MAKECALENDARID
                LEFT JOIN WORKSHIFT ws ON ws.WORKSHIFTID =r.WORKSHIFTID
                LEFT JOIN ContainerStepRecord csr ON csr.CONTAINERID =c.CONTAINERID AND csr.WORKFLOWSTEPID =api.WORKFLOWSTEPID 
                WHERE r.RESOURCENAME IS NOT NULL AND ap.ApsType2=2 and ap.ApsType=1 and c.ISINSTORE <>1 AND nvl(csr.USECOMPLETED,0) =0 and api.Isuse=0";
        DataTable dt = new DataTable();
        if (para != null)
        {
            strSQL += " and ap.CONTAINERID ='" + para["CONTAINERID"] + "'";
        }
        if (!string.IsNullOrWhiteSpace(resourCode))
        {//编码
            strSQL += " and r.ResourceName like'%" + resourCode + "%'";
        }
        if (!string.IsNullOrWhiteSpace(resourName))//名称
        {
            strSQL += " and r.DESCRIPTION like'%" + resourName + "%'";
        }
        if (!string.IsNullOrWhiteSpace(apspoolID))
        {
            strSQL += " and r.WORKCENTERID ='" + apspoolID + "'";
        }
        if (m_UserInfo != null)
        {
            strSQL += String.Format(" and c.OriginalFactoryID = '{0}' ", m_UserInfo.FactoryID.ToString());
        }
        if (!string.IsNullOrWhiteSpace(isInfinite))
        {
            strSQL += " and decode(r.isInfinite,null,0,r.isInfinite)='" + isInfinite + "'";
        }

        dt = DatabaseHelper.Query_ReturnDatTable(string.Format(strSQL, monthDay, balanceMonth, NextMonthStartDate, CurrentMonthStartDate));
        foreach (DataRow row in dt.Rows)
        {
            DataTable dayDT = getDayUseTime2(NextMonthStartDate, CurrentMonthStartDate, row["resourceID"].ToString(), balanceMonth);
            var scValue = dayDT.Compute("Sum(value)", "month='" + balanceMonth + "'");
            double sc = 0;
            double.TryParse(scValue.ToString(), out sc);
            row["UseTOTALMINS"] = Math.Round(sc, 2);
            var usetime = Convert.ToDouble(row["totalmins"].ToString()) == 0 ? 0 : Math.Round(sc / Convert.ToDouble(row["totalmins"].ToString()) * 100, 2);
            row["usetime"] = usetime;
        }
        var dv = new DataView(dt);
        dv.Sort = " usetime desc";
        dt = dv.ToTable();

        context.Response.Write(JsonConvert.SerializeObject(dt));
    }

    /// <summary>
    /// ----预排相关
    /// 设备月工作总时间=月每天设备占用时间总和
    /// 设备月可用工作总时间=日历工作天数 X 班次每天有效时间
    /// 占用率=设备月工作总时间/设备月可用工作总时间
    /// 335
    /// </summary>
    /// <param name="context"></param>
    private void getPreApsResourceData(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult();
        Dictionary<string, object> para = JsonConvert.DeserializeObject<Dictionary<string, object>>(context.Request.Form["data"].ToString());
        var resourCode = context.Request.Form["resourCode"].ToString();
        var resourName = context.Request.Form["resourName"].ToString();
        var apspoolID = context.Request.Form["apspoolID"].ToString();
        //var balanceMonth = context.Request.Form["balanceMonth"].ToString();
        var isInfinite = context.Request.Form["isInfinite"].ToString();
        var balanceStartDate = context.Request.Form["balanceStartDate"].ToString();
        var balanceEndDate = context.Request.Form["balanceEndDate"].ToString();
        var monthDay = (Convert.ToDateTime(balanceEndDate) - Convert.ToDateTime(balanceStartDate)).Days;//DateTime.DaysInMonth(Convert.ToDateTime(balanceMonth + "-01").Year, Convert.ToDateTime(balanceMonth + "-01").Month);
        var CurrentMonthStartDate = Convert.ToDateTime(balanceStartDate).ToString("yyyy-MM-dd HH:mm:ss");
        var NextMonthStartDate = Convert.ToDateTime(balanceEndDate).ToString("yyyy-MM-dd HH:mm:ss");
        var strSQL = @"SELECT DISTINCT api.RESOURCEID,r.MAKECALENDARID,r.WORKSHIFTID,nvl(r.DESCRIPTION,' ') RESOURCENAME,r.RESOURCENAME RESOURCENAMECODE,nvl(rf.RESOURCEFAMILYNAME,' ') RESOURCEFAMILYNAME,decode(ISINFINITE,'1','无限',' ')ISINFINITE,nvl(m.MakeCalendarName,' ')MakeCalendarName,nvl(ws.WORKSHIFTNAME,' ') WORKSHIFTNAME,
                (SELECT nvl(COUNT(1),0) empCOUNT FROM  employeeresourcelist esl WHERE esl.RESOURCELISTID=r.RESOURCEID) empCOUNT,
                (SELECT nvl(sum(MINS),0) MINS FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID=r.WORKSHIFTID) MINS,
                round(({0}-(SELECT COUNT(1) holiday FROM MAKECALENDARDETAIL m WHERE to_char(HOLIDAYDATE,'yyyy-MM-dd')>='{1}' AND to_char(HOLIDAYDATE,'yyyy-MM-dd')<='{2}' AND MAKECALENDARID=r.MAKECALENDARID)) 
                *(SELECT nvl(sum(MINS),0) MINS FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID=r.WORKSHIFTID)/60,2) totalmins,0 UseTOTALMINS,0 usetime
                FROM CONTAINERCURRENTINFO c 
                LEFT Join ApsPlanInfopre ap ON ap.CONTAINERID=c.CONTAINERID
                LEFT JOIN ApsPlanDetailpre api ON api.APSPLANINFOID =ap.APSPLANINFOID 
                LEFT JOIN RESOURCEDEF r ON r.RESOURCEID =api.RESOURCEID
                LEFT JOIN ResourceFamily rf ON rf.RESOURCEFAMILYID =r.RESOURCEFAMILYID                  
                LEFT JOIN MakeCalendar m ON m.MAKECALENDARID=r.MAKECALENDARID
                LEFT JOIN WORKSHIFT ws ON ws.WORKSHIFTID =r.WORKSHIFTID
                LEFT JOIN ContainerStepRecord csr ON csr.CONTAINERID =c.CONTAINERID AND csr.WORKFLOWSTEPID =api.WORKFLOWSTEPID 
                WHERE r.RESOURCENAME IS NOT NULL AND ap.ApsType2=2 and ap.ApsType=1 and c.ISINSTORE <>1 AND nvl(csr.USECOMPLETED,0) =0 and api.Isuse=0";
        DataTable dt = new DataTable();
        if (para != null)
        {
            strSQL += " and ap.CONTAINERID ='" + para["CONTAINERID"] + "'";
        }
        if (!string.IsNullOrWhiteSpace(resourCode))
        {//编码
            strSQL += " and r.ResourceName like'%" + resourCode + "%'";
        }
        if (!string.IsNullOrWhiteSpace(resourName))//名称
        {
            strSQL += " and r.DESCRIPTION like'%" + resourName + "%'";
        }
        if (!string.IsNullOrWhiteSpace(apspoolID))
        {
            strSQL += " and r.WORKCENTERID ='" + apspoolID + "'";
        }
        if (m_UserInfo != null)
        {
            strSQL += String.Format(" and c.OriginalFactoryID = '{0}' ", m_UserInfo.FactoryID.ToString());
        }
        if (!string.IsNullOrWhiteSpace(isInfinite))
        {
            strSQL += " and decode(r.isInfinite,null,0,r.isInfinite)='" + isInfinite + "'";
        }

        dt = DatabaseHelper.Query_ReturnDatTable(string.Format(strSQL, monthDay, NextMonthStartDate, CurrentMonthStartDate));
        foreach (DataRow row in dt.Rows)
        {
            DataTable dayDT = getDayUseTime2ForPre(NextMonthStartDate, CurrentMonthStartDate, row["resourceID"].ToString(), "");
            var scValue = dayDT.Compute("Sum(value)", "month>='" + CurrentMonthStartDate + "'");
            double sc = 0;
            double.TryParse(scValue.ToString(), out sc);
            row["UseTOTALMINS"] = Math.Round(sc, 2);
            var usetime = Convert.ToDouble(row["totalmins"].ToString()) == 0 ? 0 : Math.Round(sc / Convert.ToDouble(row["totalmins"].ToString()) * 100, 2);
            row["usetime"] = usetime;
        }
        var dv = new DataView(dt);
        dv.Sort = " usetime desc";
        dt = dv.ToTable();

        context.Response.Write(JsonConvert.SerializeObject(dt));
    }

    private void getApsResourceFHData(HttpContext context)
    {
        Dictionary<string, object> para = GetApsResourceFHData(context.Request.Form["resourceid"].ToString(), context.Request.Form["balanceMonth"].ToString());
        context.Response.Write(JsonConvert.SerializeObject(para));
    }

    private Dictionary<string, object> GetApsResourceFHData(string resourceID, string balanceMonth)
    {
        var monthDay = DateTime.DaysInMonth(Convert.ToDateTime(balanceMonth + "-01").Year, Convert.ToDateTime(balanceMonth + "-01").Month);
        var CurrentMonthStartDate = Convert.ToDateTime(balanceMonth + "-01").ToString("yyyy-MM-dd HH:mm:ss");
        var NextMonthStartDate = Convert.ToDateTime(balanceMonth + "-01").AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss");
        //设备每天有效工作时间
        var strSQL = @" SELECT r.RESOURCENAME , r.RESOURCEID,
                (SELECT round(nvl(SUM(MINS),0)/60,2) MINS FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID=r.WORKSHIFTID) daytotalmins
                from  RESOURCEDEF r WHERE r.RESOURCEID='" + resourceID + "'";
        DataTable dt = DatabaseHelper.Query_ReturnDatTable(strSQL);
        double daytotalmins = 0;
        if (dt.Rows.Count > 0) { daytotalmins = Convert.ToDouble(dt.Rows[0]["daytotalmins"].ToString()); }
        //设备日历休息日查询
        var calendarStr = @" SELECT to_char(m2.HOLIDAYDATE,'yyyy-MM-dd') HOLIDAYDATE,m2.ISUSE FROM RESOURCEDEF r 
               LEFT JOIN MAKECALENDARDETAIL m2 ON m2.MAKECALENDARID =r.MAKECALENDARID
               WHERE r.RESOURCEID ='" + resourceID + "'";
        DataTable cadt = DatabaseHelper.Query_ReturnDatTable(calendarStr);
        //设备每天占用时间
        DataTable dayDT = getDayUseTime2(NextMonthStartDate, CurrentMonthStartDate, resourceID, balanceMonth);
        //设备保养时间列表
        var baoyangStr = @" SELECT 
                    CASE WHEN UPKEEPENDDATE>to_date('{0}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{0}','yyyy-MM-dd hh24:mi:ss') else UPKEEPENDDATE END BUPKEEPENDDATE --月内的实际结束时间
                    ,CASE WHEN UPKEEPSTARTDATE<to_date('{1}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{1}','yyyy-MM-dd hh24:mi:ss') else UPKEEPSTARTDATE END BUPKEEPSTARTDATE --月内的实际结束时间
                    ,UPKEEPENDDATE,UPKEEPSTARTDATE
                    ,ws.STARTDATE ,ws.ENDDATE 
                    FROM ResourceUpKeepInfo rk 
                    LEFT JOIN RESOURCEDEF r ON r.RESOURCEID =rk.RESOURCEID
                	LEFT JOIN WORKSHIFT ws ON ws.WORKSHIFTID =r.WORKSHIFTID
                	where rk.RESOURCEID='{2}' --and (to_char(UPKEEPENDDATE,'yyyy-MM')='{3}' or to_char(UPKEEPSTARTDATE,'yyyy-MM')='{3}')
                ";
        DataTable dt2 = DatabaseHelper.Query_ReturnDatTable(string.Format(baoyangStr, NextMonthStartDate, CurrentMonthStartDate, resourceID, balanceMonth));
        DataTable byDT = dayDT.Clone();
        foreach (DataRow row in dt2.Rows)
        {
            var diffday = Math.Ceiling(DiffDays(Convert.ToDateTime(Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString()).ToString("yyyy-MM-dd")), Convert.ToDateTime(Convert.ToDateTime(row["UPKEEPENDDATE"].ToString()).ToString("yyyy-MM-dd"))));
            if (diffday == 0)//开始/结束是同一天，
            {
                DataRow dayRow = byDT.NewRow();
                dayRow["date"] = Convert.ToDateTime(row["UPKEEPENDDATE"].ToString()).ToString("yyyy-MM-dd");
                var bcStartDate = Convert.ToDateTime(dayRow["date"].ToString() + " " + row["STARTDATE"].ToString());
                var bcendDate = Convert.ToDateTime(dayRow["date"].ToString() + " " + row["ENDDATE"].ToString());
                var UPKEEPSTARTDATE = Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString());
                var UPKEEPENDDATE = Convert.ToDateTime(row["UPKEEPENDDATE"].ToString());
                if (UPKEEPSTARTDATE >= bcStartDate && UPKEEPENDDATE <= bcendDate)
                {//保养（开始/结束）在班次开工有效时间内
                    dayRow["value"] = DiffHours(UPKEEPSTARTDATE, UPKEEPENDDATE);
                }
                else if (UPKEEPSTARTDATE > bcStartDate && UPKEEPENDDATE > bcendDate)
                {
                    dayRow["value"] = DiffHours(UPKEEPSTARTDATE, bcendDate);
                }
                else if (UPKEEPSTARTDATE < bcStartDate && UPKEEPENDDATE < bcendDate)//保养开始<班次开始 && 保养结束<班次结束
                {
                    dayRow["value"] = DiffHours(bcStartDate, UPKEEPENDDATE);
                }
                else if (UPKEEPSTARTDATE < bcStartDate && UPKEEPENDDATE > bcendDate)//保养开始<班次开始 && 保养结束>班次结束
                {
                    dayRow["value"] = DiffHours(bcStartDate, bcendDate);
                }
                else //保养开始>班次结束（不在班次开工有效时间范围内） (UPKEEPSTARTDATE > bcendDate)
                {
                    dayRow["value"] = 0;
                }
                byDT.Rows.Add(dayRow);
            }
            if (diffday > 0)//开始/结束跨天
            {
                for (var j = 0; j <= diffday; j++)
                {
                    DataRow dayRow1 = byDT.NewRow();
                    dayRow1["date"] = Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString()).AddDays(j).ToString("yyyy-MM-dd");
                    var UPKEEPSTARTDATE = Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString());
                    var UPKEEPENDDATE = Convert.ToDateTime(row["UPKEEPENDDATE"].ToString());
                    if (j == 0)//开始第一天（班次结束时间是否维护，否：加一天的00:00:00；是：ENDDATE）
                    {
                        var endDate = string.IsNullOrWhiteSpace(row["ENDDATE"].ToString()) ? Convert.ToDateTime(dayRow1["date"].ToString()).AddDays(1) : Convert.ToDateTime(dayRow1["date"] + " " + row["ENDDATE"].ToString());
                        var startDate = Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                        if (UPKEEPSTARTDATE > startDate) { dayRow1["value"] = DiffHours(UPKEEPSTARTDATE, endDate); }//设备保养开始时间>班次开始时间
                        if (UPKEEPSTARTDATE < startDate) { dayRow1["value"] = DiffHours(startDate, endDate); }//设备保养开始时间<班次开始时间
                    }
                    else if (j == diffday) //最后一天（班次开始时间是否维护，否：00:00:00；是：STARTDATE）
                    {
                        var startDate = string.IsNullOrWhiteSpace(row["STARTDATE"].ToString()) ? Convert.ToDateTime(dayRow1["date"].ToString()) : Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                        var endDate = Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());//班次结束时间
                        if (UPKEEPENDDATE < endDate) { dayRow1["value"] = DiffHours(startDate, UPKEEPENDDATE); }//设备保养结束时间< 班次结束时间
                        if (UPKEEPENDDATE > endDate) { dayRow1["value"] = DiffHours(startDate, endDate); }//设备保养结束时间> 班次结束时间
                    }
                    else//中间天
                    {
                        dayRow1["value"] = 24;
                        if (!string.IsNullOrWhiteSpace(row["STARTDATE"].ToString()))
                        {
                            var startDate = Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                            var endDate = Convert.ToDateTime(dayRow1["date"] + " " + row["ENDDATE"].ToString());
                            dayRow1["value"] = DiffHours(startDate, endDate);
                        }
                    }
                    byDT.Rows.Add(dayRow1);
                }
            }
        }

        var scStr = new ArrayList();
        var xzStr = new ArrayList();
        var djStr = new ArrayList();
        for (var j = 1; j <= monthDay; j++)
        {
            var date = Convert.ToDateTime(CurrentMonthStartDate).AddDays(j - 1).ToString("yyyy-MM-dd");
            DataRow[] ExistDate = cadt.Select("HOLIDAYDATE='" + date + "'");//判断日期是否休息（休假）
            if (ExistDate.Length == 0)
            {
                var scValue = dayDT.Compute("Sum(value)", "date='" + date + "'");
                double sc = 0;
                double.TryParse(scValue.ToString(), out sc);
                if (sc > 0)
                {
                    scStr.Add(Math.Round(sc, 2));
                }
                else { scStr.Add(""); }
                var djValue = byDT.Compute("Sum(value)", "date='" + date + "'");
                double dj = 0;
                double.TryParse(djValue.ToString(), out dj);
                if (dj > 0) { djStr.Add(Math.Round(dj, 2)); } else { djStr.Add(""); }
                var xzValue = daytotalmins - sc - dj;
                if (xzValue > 0) { xzStr.Add(Math.Round(xzValue, 2)); } else { xzStr.Add(""); }

            }
            else
            {
                scStr.Add("");
                xzStr.Add("");
                djStr.Add("");
            }
        }
        var para = new Dictionary<string, object>();
        para.Add("scdata", scStr);
        para.Add("xzdata", xzStr);
        para.Add("fhdata", djStr);
        para.Add("days", monthDay);
        return para;
    }

    private void getPreApsResourceFHData(HttpContext context)
    {
        Dictionary<string, object> para = getPreApsResourceFHData(context.Request.Form["resourceid"].ToString(), context.Request.Form["balanceStartDate"].ToString(), context.Request.Form["balanceEndDate"].ToString());
        context.Response.Write(JsonConvert.SerializeObject(para));
    }

    private Dictionary<string, object> getPreApsResourceFHData(string resourceID, string balanceStartDate, string balanceEndDate)
    {
        var monthDay = (Convert.ToDateTime(balanceEndDate) - Convert.ToDateTime(balanceStartDate)).Days; //DateTime.DaysInMonth(Convert.ToDateTime(balanceMonth + "-01").Year, Convert.ToDateTime(balanceMonth + "-01").Month);
        var CurrentMonthStartDate = Convert.ToDateTime(balanceStartDate).ToString("yyyy-MM-dd HH:mm:ss");
        var NextMonthStartDate = Convert.ToDateTime(balanceEndDate).ToString("yyyy-MM-dd HH:mm:ss");
        //设备每天有效工作时间
        var strSQL = @" SELECT r.RESOURCENAME , r.RESOURCEID,
                (SELECT round(nvl(SUM(MINS),0)/60,2) MINS FROM WorkShiftDetail wsd WHERE wsd.WORKSHIFTID=r.WORKSHIFTID) daytotalmins
                from  RESOURCEDEF r WHERE r.RESOURCEID='" + resourceID + "'";
        DataTable dt = DatabaseHelper.Query_ReturnDatTable(strSQL);
        double daytotalmins = 0;
        if (dt.Rows.Count > 0) { daytotalmins = Convert.ToDouble(dt.Rows[0]["daytotalmins"].ToString()); }
        //设备日历休息日查询
        var calendarStr = @" SELECT to_char(m2.HOLIDAYDATE,'yyyy-MM-dd') HOLIDAYDATE,m2.ISUSE FROM RESOURCEDEF r 
               LEFT JOIN MAKECALENDARDETAIL m2 ON m2.MAKECALENDARID =r.MAKECALENDARID
               WHERE r.RESOURCEID ='" + resourceID + "'";
        DataTable cadt = DatabaseHelper.Query_ReturnDatTable(calendarStr);
        //设备每天占用时间
        DataTable dayDT = getDayUseTime2ForPre(NextMonthStartDate, CurrentMonthStartDate, resourceID, "");
        //设备保养时间列表
        var baoyangStr = @" SELECT 
                    CASE WHEN UPKEEPENDDATE>to_date('{0}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{0}','yyyy-MM-dd hh24:mi:ss') else UPKEEPENDDATE END BUPKEEPENDDATE --月内的实际结束时间
                    ,CASE WHEN UPKEEPSTARTDATE<to_date('{1}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{1}','yyyy-MM-dd hh24:mi:ss') else UPKEEPSTARTDATE END BUPKEEPSTARTDATE --月内的实际结束时间
                    ,UPKEEPENDDATE,UPKEEPSTARTDATE
                    ,ws.STARTDATE ,ws.ENDDATE 
                    FROM ResourceUpKeepInfo rk 
                    LEFT JOIN RESOURCEDEF r ON r.RESOURCEID =rk.RESOURCEID
                	LEFT JOIN WORKSHIFT ws ON ws.WORKSHIFTID =r.WORKSHIFTID
                	where rk.RESOURCEID='{2}' --and (to_char(UPKEEPENDDATE,'yyyy-MM')='{3}' or to_char(UPKEEPSTARTDATE,'yyyy-MM')='{3}')
                ";
        DataTable dt2 = DatabaseHelper.Query_ReturnDatTable(string.Format(baoyangStr, NextMonthStartDate, CurrentMonthStartDate, resourceID, ""));
        DataTable byDT = dayDT.Clone();
        foreach (DataRow row in dt2.Rows)
        {
            var diffday = Math.Ceiling(DiffDays(Convert.ToDateTime(Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString()).ToString("yyyy-MM-dd")), Convert.ToDateTime(Convert.ToDateTime(row["UPKEEPENDDATE"].ToString()).ToString("yyyy-MM-dd"))));
            if (diffday == 0)//开始/结束是同一天，
            {
                DataRow dayRow = byDT.NewRow();
                dayRow["date"] = Convert.ToDateTime(row["UPKEEPENDDATE"].ToString()).ToString("yyyy-MM-dd");
                var bcStartDate = Convert.ToDateTime(dayRow["date"].ToString() + " " + row["STARTDATE"].ToString());
                var bcendDate = Convert.ToDateTime(dayRow["date"].ToString() + " " + row["ENDDATE"].ToString());
                var UPKEEPSTARTDATE = Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString());
                var UPKEEPENDDATE = Convert.ToDateTime(row["UPKEEPENDDATE"].ToString());
                if (UPKEEPSTARTDATE >= bcStartDate && UPKEEPENDDATE <= bcendDate)
                {//保养（开始/结束）在班次开工有效时间内
                    dayRow["value"] = DiffHours(UPKEEPSTARTDATE, UPKEEPENDDATE);
                }
                else if (UPKEEPSTARTDATE > bcStartDate && UPKEEPENDDATE > bcendDate)
                {
                    dayRow["value"] = DiffHours(UPKEEPSTARTDATE, bcendDate);
                }
                else if (UPKEEPSTARTDATE < bcStartDate && UPKEEPENDDATE < bcendDate)//保养开始<班次开始 && 保养结束<班次结束
                {
                    dayRow["value"] = DiffHours(bcStartDate, UPKEEPENDDATE);
                }
                else if (UPKEEPSTARTDATE < bcStartDate && UPKEEPENDDATE > bcendDate)//保养开始<班次开始 && 保养结束>班次结束
                {
                    dayRow["value"] = DiffHours(bcStartDate, bcendDate);
                }
                else //保养开始>班次结束（不在班次开工有效时间范围内） (UPKEEPSTARTDATE > bcendDate)
                {
                    dayRow["value"] = 0;
                }
                byDT.Rows.Add(dayRow);
            }
            if (diffday > 0)//开始/结束跨天
            {
                for (var j = 0; j <= diffday; j++)
                {
                    DataRow dayRow1 = byDT.NewRow();
                    dayRow1["date"] = Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString()).AddDays(j).ToString("yyyy-MM-dd");
                    var UPKEEPSTARTDATE = Convert.ToDateTime(row["UPKEEPSTARTDATE"].ToString());
                    var UPKEEPENDDATE = Convert.ToDateTime(row["UPKEEPENDDATE"].ToString());
                    if (j == 0)//开始第一天（班次结束时间是否维护，否：加一天的00:00:00；是：ENDDATE）
                    {
                        var endDate = string.IsNullOrWhiteSpace(row["ENDDATE"].ToString()) ? Convert.ToDateTime(dayRow1["date"].ToString()).AddDays(1) : Convert.ToDateTime(dayRow1["date"] + " " + row["ENDDATE"].ToString());
                        var startDate = Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                        if (UPKEEPSTARTDATE > startDate) { dayRow1["value"] = DiffHours(UPKEEPSTARTDATE, endDate); }//设备保养开始时间>班次开始时间
                        if (UPKEEPSTARTDATE < startDate) { dayRow1["value"] = DiffHours(startDate, endDate); }//设备保养开始时间<班次开始时间
                    }
                    else if (j == diffday) //最后一天（班次开始时间是否维护，否：00:00:00；是：STARTDATE）
                    {
                        var startDate = string.IsNullOrWhiteSpace(row["STARTDATE"].ToString()) ? Convert.ToDateTime(dayRow1["date"].ToString()) : Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                        var endDate = Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());//班次结束时间
                        if (UPKEEPENDDATE < endDate) { dayRow1["value"] = DiffHours(startDate, UPKEEPENDDATE); }//设备保养结束时间< 班次结束时间
                        if (UPKEEPENDDATE > endDate) { dayRow1["value"] = DiffHours(startDate, endDate); }//设备保养结束时间> 班次结束时间
                    }
                    else//中间天
                    {
                        dayRow1["value"] = 24;
                        if (!string.IsNullOrWhiteSpace(row["STARTDATE"].ToString()))
                        {
                            var startDate = Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                            var endDate = Convert.ToDateTime(dayRow1["date"] + " " + row["ENDDATE"].ToString());
                            dayRow1["value"] = DiffHours(startDate, endDate);
                        }
                    }
                    byDT.Rows.Add(dayRow1);
                }
            }
        }

        var scStr = new ArrayList();
        var xzStr = new ArrayList();
        var djStr = new ArrayList();
        var fhStr = new ArrayList();// add by zhangrj 20241224
        for (var j = 1; j <= monthDay; j++)
        {
            var date = Convert.ToDateTime(CurrentMonthStartDate).AddDays(j - 1).ToString("yyyy-MM-dd");
            DataRow[] ExistDate = cadt.Select("HOLIDAYDATE='" + date + "'");//判断日期是否休息（休假）
            if (ExistDate.Length == 0)
            {
                var scValue = dayDT.Compute("Sum(value)", "date='" + date + "'");
                double sc = 0;
                double.TryParse(scValue.ToString(), out sc);
                if (sc > 0)
                {
                    double scV = Math.Round(sc, 2);
                    scStr.Add(scV);
                    fhStr.Add(Math.Round((scV / daytotalmins)*100, 2)+"%");// add by zhangrj 20241224 
                }
                else { scStr.Add(""); fhStr.Add(""); }
                var djValue = byDT.Compute("Sum(value)", "date='" + date + "'");
                double dj = 0;
                double.TryParse(djValue.ToString(), out dj);
                if (dj > 0) { djStr.Add(Math.Round(dj, 2)); } else { djStr.Add(""); }
                var xzValue = daytotalmins - sc - dj;
                if (xzValue > 0) { xzStr.Add(Math.Round(xzValue, 2)); } else { xzStr.Add(""); }

            }
            else
            {
                scStr.Add("");
                xzStr.Add("");
                djStr.Add("");
                fhStr.Add("");
            }
        }
        var para = new Dictionary<string, object>();
        para.Add("scdata", scStr);
        para.Add("xzdata", xzStr);
        para.Add("djdata", djStr);
        para.Add("fhdata", fhStr);
        para.Add("days", monthDay);
        return para;
    }



    //设备每天占用时间
    private DataTable getDayUseTime(string NextMonthStartDate, string CurrentMonthStartDate, string resourceID, string balanceMonth)
    {
        DataTable dayDT = new DataTable();
        dayDT.Columns.Add("date");
        dayDT.Columns.Add("month");
        dayDT.Columns.Add("value", typeof(double));
        //1.先查询一个月内的所有数据;2.判断每天开始/结束时间是否在有效班次工作时间内，不在则是在多天执行，分成多条数据  TO_NUMBER(RESENDTIME-RESSTARTTIME)*24 diffday,
        var strSQL1 = @"SELECT RESSTARTTIME,RESENDTIME,STARTDATE,ENDDATE FROM( 
              	select CASE WHEN RESENDTIME>to_date('{0}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{0}','yyyy-MM-dd hh24:mi:ss') else RESENDTIME END BRESENDTIME --月内的实际结束时间
                    ,CASE WHEN RESSTARTTIME<to_date('{1}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{1}','yyyy-MM-dd hh24:mi:ss') else RESSTARTTIME END BRESSTARTTIME --月内的实际结束时间
                ,ws.STARTDATE ,ws.ENDDATE,api.RESSTARTTIME, api.RESENDTIME
                    from ApsPlanDetail api
                LEFT Join ApsPlanInfo ap ON api.APSPLANINFOID =ap.APSPLANINFOID 
                LEFT JOIN RESOURCEDEF r ON r.RESOURCEID =api.RESOURCEID
                LEFT JOIN WORKSHIFT ws ON ws.WORKSHIFTID =r.WORKSHIFTID
                LEFT JOIN CONTAINERCURRENTINFO cci ON cci.CONTAINERID =ap.CONTAINERID  
                where api.RESOURCEID='{2}' AND ap.ApsType2=2 and ap.ApsType=1 AND cci.ISINSTORE <>1 and ('{3}' BETWEEN to_char(api.RESSTARTTIME,'yyyy-MM') AND to_char(api.RESENDTIME,'yyyy-MM')) 
              ) --WHERE RESENDTIME>RESSTARTTIME
              order by RESSTARTTIME
                ";
        DataTable dt1 = DatabaseHelper.Query_ReturnDatTable(string.Format(strSQL1, NextMonthStartDate, CurrentMonthStartDate, resourceID, balanceMonth));

        foreach (DataRow row in dt1.Rows)
        {
            var s = row["RESSTARTTIME"].ToString();
            var diffday = Math.Ceiling(DiffDays(Convert.ToDateTime(Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM-dd")), Convert.ToDateTime(Convert.ToDateTime(row["RESENDTIME"].ToString()).ToString("yyyy-MM-dd"))));
            if (diffday == 0)//开始/结束是同一天，
            {
                DataRow dayRow = dayDT.NewRow();
                dayRow["date"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM-dd");
                dayRow["month"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM");
                var RESSTARTTIME = Convert.ToDateTime(row["RESSTARTTIME"].ToString());//设备实际开始时间
                var RESENDTIME = Convert.ToDateTime(row["RESENDTIME"].ToString());//设备实际结束时间
                var endDate = string.IsNullOrWhiteSpace(row["ENDDATE"].ToString()) ? Convert.ToDateTime(dayRow["date"].ToString()).AddDays(1) : Convert.ToDateTime(dayRow["date"] + " " + row["ENDDATE"].ToString());//班次有效结束
                var startDate = string.IsNullOrWhiteSpace(row["STARTDATE"].ToString()) ? Convert.ToDateTime(dayRow["date"].ToString()) : Convert.ToDateTime(dayRow["date"] + " " + row["STARTDATE"].ToString());//班次有效开始
                if (RESSTARTTIME > startDate && RESENDTIME < endDate)
                {
                    dayRow["value"] = DiffHours(RESSTARTTIME, RESENDTIME);
                }
                else if (RESSTARTTIME > startDate && RESENDTIME > endDate && RESSTARTTIME < endDate)
                {
                    dayRow["value"] = DiffHours(RESSTARTTIME, endDate);
                }
                else if (RESSTARTTIME < startDate && RESENDTIME > endDate)
                {
                    dayRow["value"] = DiffHours(startDate, endDate);
                }
                else if (RESSTARTTIME < startDate && RESENDTIME < endDate && RESENDTIME > startDate)
                {
                    dayRow["value"] = DiffHours(startDate, RESENDTIME);
                }
                else
                {
                    dayRow["value"] = 0;
                }

                dayDT.Rows.Add(dayRow);
            }
            if (diffday > 0)//开始/结束跨天
            {
                for (var j = 0; j <= diffday; j++)
                {
                    DataRow dayRow1 = dayDT.NewRow();
                    dayRow1["date"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).AddDays(j).ToString("yyyy-MM-dd");
                    dayRow1["month"] = Convert.ToDateTime(dayRow1["date"]).ToString("yyyy-MM");
                    if (j == 0)//开始第一天（班次结束时间是否维护，否：加一天的00:00:00；是：ENDDATE）
                    {
                        var endDate = string.IsNullOrWhiteSpace(row["ENDDATE"].ToString()) ? Convert.ToDateTime(dayRow1["date"].ToString()).AddDays(1) : Convert.ToDateTime(dayRow1["date"] + " " + row["ENDDATE"].ToString());
                        var startDate = Convert.ToDateTime(row["RESSTARTTIME"].ToString());
                        dayRow1["value"] = startDate < endDate ? DiffHours(startDate, endDate) : 0;//设备开始时间
                    }
                    else if (j == diffday) //最后一天（班次开始时间是否维护，否：00:00:00；是：STARTDATE）
                    {
                        var startDate = string.IsNullOrWhiteSpace(row["STARTDATE"].ToString()) ? Convert.ToDateTime(dayRow1["date"].ToString()) : Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                        var endDate = Convert.ToDateTime(row["RESENDTIME"].ToString());
                        dayRow1["value"] = endDate < startDate ? 0 : DiffHours(startDate, endDate);//设备结束时间
                    }
                    else//中间天
                    {
                        if (!string.IsNullOrWhiteSpace(row["STARTDATE"].ToString()))
                        {
                            var startDate = Convert.ToDateTime(dayRow1["date"] + " " + row["STARTDATE"].ToString());
                            var endDate = Convert.ToDateTime(dayRow1["date"] + " " + row["ENDDATE"].ToString());
                            dayRow1["value"] = DiffHours(startDate, endDate);
                        }
                        else
                        {
                            dayRow1["value"] = 24;
                        }
                    }

                    dayDT.Rows.Add(dayRow1);
                }
            }
        }
        return dayDT;
    }

    private DataTable getDayUseTime2(string NextMonthStartDate, string CurrentMonthStartDate, string resourceID, string balanceMonth)
    {
        DataTable dayDT = new DataTable();
        dayDT.Columns.Add("date");
        dayDT.Columns.Add("month");
        dayDT.Columns.Add("value", typeof(double));
        //1.先查询一个月内的所有数据;2.判断每天开始/结束时间是否在有效班次工作时间内，不在则是在多天执行，分成多条数据  TO_NUMBER(RESENDTIME-RESSTARTTIME)*24 diffday,
        var strSQL1 = @"SELECT RESSTARTTIME,RESENDTIME,STARTDATE,ENDDATE FROM( 
              	select CASE WHEN RESENDTIME>to_date('{0}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{0}','yyyy-MM-dd hh24:mi:ss') else RESENDTIME END BRESENDTIME --月内的实际结束时间
                    ,CASE WHEN RESSTARTTIME<to_date('{1}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{1}','yyyy-MM-dd hh24:mi:ss') else RESSTARTTIME END BRESSTARTTIME --月内的实际结束时间
                ,ws.STARTDATE ,ws.ENDDATE,api.RESSTARTTIME RESSTARTTIME2, api.RESENDTIME,(RESENDTIME-NUMTODSINTERVAL(nvl(WS.PREPARECYCLE,0), 'MINUTE')-NUMTODSINTERVAL(nvl(WS.MAKECYCLE,0)*api.qty, 'MINUTE')) RESSTARTTIME
                    from ApsPlanDetail api
                LEFT Join ApsPlanInfo ap ON api.APSPLANINFOID =ap.APSPLANINFOID 
                LEFT JOIN RESOURCEDEF r ON r.RESOURCEID =api.RESOURCEID
                LEFT JOIN WORKSHIFT ws ON ws.WORKSHIFTID =r.WORKSHIFTID
                LEFT JOIN CONTAINERCURRENTINFO cci ON cci.CONTAINERID =ap.CONTAINERID
                LEFT JOIN ContainerStepRecord csr ON csr.CONTAINERID =cci.CONTAINERID AND csr.WORKFLOWSTEPID =api.WORKFLOWSTEPID
                LEFT JOIN workflowstep ws on ws.workflowstepid=api.workflowstepid   
                where api.RESOURCEID='{2}' AND ap.ApsType2=2 and ap.ApsType=1 AND cci.ISINSTORE <>1 AND nvl(csr.USECOMPLETED,0)=0  and api.Isuse=0--AND csr.usecompleted<>1
                and ('{3}' BETWEEN to_char(api.RESSTARTTIME,'yyyy-MM') AND to_char(api.RESENDTIME,'yyyy-MM')) 
              ) --WHERE RESENDTIME>RESSTARTTIME
              order by RESSTARTTIME
                ";
        DataTable dt1 = DatabaseHelper.Query_ReturnDatTable(string.Format(strSQL1, NextMonthStartDate, CurrentMonthStartDate, resourceID, balanceMonth));
        //设备日历休息日查询
        var calendarStr = @" SELECT to_char(m2.HOLIDAYDATE,'yyyy-MM-dd') HOLIDAYDATE,m2.ISUSE FROM RESOURCEDEF r 
               LEFT JOIN MAKECALENDARDETAIL m2 ON m2.MAKECALENDARID =r.MAKECALENDARID
               WHERE r.RESOURCEID ='" + resourceID + "'";
        DataTable cadt = DatabaseHelper.Query_ReturnDatTable(calendarStr);

        foreach (DataRow row in dt1.Rows)
        {
            var s = row["RESSTARTTIME"].ToString();
            var diffday = Math.Ceiling(DiffDays(Convert.ToDateTime(Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM-dd")), Convert.ToDateTime(Convert.ToDateTime(row["RESENDTIME"].ToString()).ToString("yyyy-MM-dd"))));
            if (diffday == 0)//开始/结束是同一天，
            {
                DataRow dayRow = dayDT.NewRow();
                dayRow["date"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM-dd");
                dayRow["month"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM");
                var RESSTARTTIME = Convert.ToDateTime(row["RESSTARTTIME"].ToString());//设备实际开始时间
                var RESENDTIME = Convert.ToDateTime(row["RESENDTIME"].ToString());//设备实际结束时间
                dayRow["value"] = DiffHours(RESSTARTTIME, RESENDTIME);
                DataRow[] ExistDate = cadt.Select("HOLIDAYDATE='" + dayRow["date"] + "'");//判断日期是否休息（休假）
                if (ExistDate.Length == 0) { dayDT.Rows.Add(dayRow); }
            }
            if (diffday > 0)//开始/结束跨天
            {
                for (var j = 0; j <= diffday; j++)
                {
                    DataRow dayRow1 = dayDT.NewRow();
                    dayRow1["date"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).AddDays(j).ToString("yyyy-MM-dd");
                    dayRow1["month"] = Convert.ToDateTime(dayRow1["date"]).ToString("yyyy-MM");
                    if (j == 0)//开始第一天（班次结束时间是否维护，否：加一天的00:00:00；是：ENDDATE）
                    {
                        var endDate = Convert.ToDateTime(dayRow1["date"].ToString()).AddDays(1);
                        var startDate = Convert.ToDateTime(row["RESSTARTTIME"].ToString());
                        dayRow1["value"] = startDate < endDate ? DiffHours(startDate, endDate) : 0;//设备开始时间
                    }
                    else if (j == diffday) //最后一天（班次开始时间是否维护，否：00:00:00；是：STARTDATE）
                    {
                        var startDate = Convert.ToDateTime(dayRow1["date"].ToString());
                        var endDate = Convert.ToDateTime(row["RESENDTIME"].ToString());
                        dayRow1["value"] = endDate < startDate ? 0 : DiffHours(startDate, endDate);//设备结束时间
                    }
                    else//中间天
                    {
                        dayRow1["value"] = 24;
                    }
                    DataRow[] ExistDate = cadt.Select("HOLIDAYDATE='" + dayRow1["date"] + "'");//判断日期是否休息（休假）
                    if (ExistDate.Length == 0) { dayDT.Rows.Add(dayRow1); }
                }
            }
        }
        return dayDT;
    }

    /// <summary>
    /// 设备占用时间（预排相关）
    /// </summary>
    /// <param name="NextMonthStartDate"></param>
    /// <param name="CurrentMonthStartDate"></param>
    /// <param name="resourceID"></param>
    /// <param name="balanceMonth"></param>
    /// <returns></returns>
    private DataTable getDayUseTime2ForPre(string NextMonthStartDate, string CurrentMonthStartDate, string resourceID, string balanceMonth)
    {
        DataTable dayDT = new DataTable();
        dayDT.Columns.Add("date");
        dayDT.Columns.Add("month");
        dayDT.Columns.Add("value", typeof(double));
        //1.先查询一个月内的所有数据;2.判断每天开始/结束时间是否在有效班次工作时间内，不在则是在多天执行，分成多条数据  TO_NUMBER(RESENDTIME-RESSTARTTIME)*24 diffday,
        var strSQL1 = @"SELECT RESSTARTTIME,RESENDTIME,STARTDATE,ENDDATE FROM( 
              	select CASE WHEN RESENDTIME>to_date('{0}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{0}','yyyy-MM-dd hh24:mi:ss') else RESENDTIME END BRESENDTIME --月内的实际结束时间
                    ,CASE WHEN RESSTARTTIME<to_date('{1}','yyyy-MM-dd hh24:mi:ss') THEN to_date('{1}','yyyy-MM-dd hh24:mi:ss') else RESSTARTTIME END BRESSTARTTIME --月内的实际结束时间
                ,ws.STARTDATE ,ws.ENDDATE,api.RESSTARTTIME RESSTARTTIME1, api.RESENDTIME,(RESENDTIME-NUMTODSINTERVAL(nvl(WS.preparecycle,0), 'MINUTE')-NUMTODSINTERVAL(nvl(WS.makecycle,0)*api.qty, 'MINUTE')) RESSTARTTIME 
                    from ApsPlanDetailpre api
                LEFT Join ApsPlanInfopre ap ON api.APSPLANINFOID =ap.APSPLANINFOID 
                LEFT JOIN RESOURCEDEF r ON r.RESOURCEID =api.RESOURCEID
                LEFT JOIN WORKSHIFT ws ON ws.WORKSHIFTID =r.WORKSHIFTID
                LEFT JOIN CONTAINERCURRENTINFO cci ON cci.CONTAINERID =ap.CONTAINERID
                LEFT JOIN ContainerStepRecord csr ON csr.CONTAINERID =cci.CONTAINERID AND csr.WORKFLOWSTEPID =api.WORKFLOWSTEPID 
                LEFT JOIN workflowstep ws on ws.workflowstepid=api.workflowstepid                                  
                where api.RESOURCEID='{2}' AND ap.ApsType2=2 and ap.ApsType=1 AND cci.ISINSTORE <>1 AND nvl(csr.USECOMPLETED,0)=0  and api.Isuse=0--AND csr.usecompleted<>1
                --and ('3' BETWEEN to_char(api.RESSTARTTIME,'yyyy-MM') AND to_char(api.RESENDTIME,'yyyy-MM')) 
                and to_char(api.RESSTARTTIME,'yyyy-MM-dd')>='{1}' and to_char(api.RESENDTIME,'yyyy-MM')<='{0}'
              ) --WHERE RESENDTIME>RESSTARTTIME
              order by RESSTARTTIME
                ";
        DataTable dt1 = DatabaseHelper.Query_ReturnDatTable(string.Format(strSQL1, NextMonthStartDate, CurrentMonthStartDate, resourceID));
        //设备日历休息日查询
        var calendarStr = @" SELECT to_char(m2.HOLIDAYDATE,'yyyy-MM-dd') HOLIDAYDATE,m2.ISUSE FROM RESOURCEDEF r 
               LEFT JOIN MAKECALENDARDETAIL m2 ON m2.MAKECALENDARID =r.MAKECALENDARID
               WHERE r.RESOURCEID ='" + resourceID + "'";
        DataTable cadt = DatabaseHelper.Query_ReturnDatTable(calendarStr);

        foreach (DataRow row in dt1.Rows)
        {
            var s = row["RESSTARTTIME"].ToString();
            var diffday = Math.Ceiling(DiffDays(Convert.ToDateTime(Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM-dd")), Convert.ToDateTime(Convert.ToDateTime(row["RESENDTIME"].ToString()).ToString("yyyy-MM-dd"))));
            if (diffday == 0)//开始/结束是同一天，
            {
                DataRow dayRow = dayDT.NewRow();
                dayRow["date"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM-dd");
                dayRow["month"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).ToString("yyyy-MM-dd");
                var RESSTARTTIME = Convert.ToDateTime(row["RESSTARTTIME"].ToString());//设备实际开始时间
                var RESENDTIME = Convert.ToDateTime(row["RESENDTIME"].ToString());//设备实际结束时间
                dayRow["value"] = DiffHours(RESSTARTTIME, RESENDTIME);
                DataRow[] ExistDate = cadt.Select("HOLIDAYDATE='" + dayRow["date"] + "'");//判断日期是否休息（休假）
                if (ExistDate.Length == 0) { dayDT.Rows.Add(dayRow); }
            }
            if (diffday > 0)//开始/结束跨天
            {
                for (var j = 0; j <= diffday; j++)
                {
                    DataRow dayRow1 = dayDT.NewRow();
                    dayRow1["date"] = Convert.ToDateTime(row["RESSTARTTIME"].ToString()).AddDays(j).ToString("yyyy-MM-dd");
                    dayRow1["month"] = Convert.ToDateTime(dayRow1["date"]).ToString("yyyy-MM-dd");
                    if (j == 0)//开始第一天（班次结束时间是否维护，否：加一天的00:00:00；是：ENDDATE）
                    {
                        var endDate = Convert.ToDateTime(dayRow1["date"].ToString()).AddDays(1);
                        var startDate = Convert.ToDateTime(row["RESSTARTTIME"].ToString());
                        dayRow1["value"] = startDate < endDate ? DiffHours(startDate, endDate) : 0;//设备开始时间
                    }
                    else if (j == diffday) //最后一天（班次开始时间是否维护，否：00:00:00；是：STARTDATE）
                    {
                        var startDate = Convert.ToDateTime(dayRow1["date"].ToString());
                        var endDate = Convert.ToDateTime(row["RESENDTIME"].ToString());
                        dayRow1["value"] = endDate < startDate ? 0 : DiffHours(startDate, endDate);//设备结束时间
                    }
                    else//中间天
                    {
                        dayRow1["value"] = 24;
                    }
                    DataRow[] ExistDate = cadt.Select("HOLIDAYDATE='" + dayRow1["date"] + "'");//判断日期是否休息（休假）
                    if (ExistDate.Length == 0) { dayDT.Rows.Add(dayRow1); }
                }
            }
        }
        return dayDT;
    }

    //时间相差小时数
    public double DiffHours(DateTime startTime, DateTime endTime)
    {
        TimeSpan hoursSpan = new TimeSpan(endTime.Ticks - startTime.Ticks);
        return hoursSpan.TotalHours;
    }
    //时间相差天数
    public double DiffDays(DateTime startTime, DateTime endTime)
    {
        TimeSpan daysSpan = new TimeSpan(endTime.Ticks - startTime.Ticks);
        return daysSpan.TotalDays;
    }

    /// <summary>
    /// 设备日排产数据
    /// </summary>
    /// <param name="context"></param>
    private void GetStepLimitedAps(HttpContext context)
    {
        var resourceID = context.Request["resourceID"].ToString();
        var date = Convert.ToDateTime(context.Request["date"].ToString());
        var type = context.Request["type"].ToString();
        uMESProcessResult result = new uMESProcessResult();
        var strSql = @"select  cci.mfgordername,cci.containername,WB.WORKFLOWNAME||':'||W.WORKFLOWREVISION WORKFLOWINFO,cci.WORKFLOWSTEPNAME CWFNAME,ad.workflowstepname,nvl(sb.revofrcdid,ws.specid) specid,ad.apsplandetailid,to_char(ad.starttime,'yyyy-MM-dd hh24:mi:ss') stepstarttime,to_char(ad.endtime,'yyyy-MM-dd hh24:mi:ss') stependtime,
              decode(re.resourcename,null,'',re.description||'('||re.resourcename||')') RESNAME,to_char(RESSTARTTIME,'yyyy-MM-dd hh24:mi:ss')RESSTARTTIME1,(RESENDTIME-NUMTODSINTERVAL(nvl(WS.preparecycle,0), 'MINUTE')-NUMTODSINTERVAL(nvl(WS.makecycle,0)*ad.qty, 'MINUTE')) RESSTARTTIME,to_char(RESENDTIME,'yyyy-MM-dd hh24:mi:ss') RESENDTIME,
              wc.workcentername,t.teamname,ad.qty,re.resourceid,wc.workcenterid,t.teamid,WS.MAKEEMPCOUNTS,WS.PREPARECYCLE,WS.MAKECYCLE,round(WS.TRANSFERCYCLE/60,2) TRANSFERCYCLE,WS.SHIPCYCLE,WS.COMMICYCLE,ws.sequence,null resorces,null dayTime
            from ApsPlanInfo ai 
            left join containercurrentinfo cci on cci.containerid=ai.containerid
            left join ApsPlanDetail ad on ad.apsplaninfoid=ai.apsplaninfoid and ad.isuse=0
            left join workflowstep ws on ws.workflowstepid=ad.workflowstepid
            left join specbase sb on sb.specbaseid=ws.specbaseid
            left join resourcedef re on re.resourceid=ad.resourceid
            LEFT JOIN CONTAINER C ON C.CONTAINERID=CCI.CONTAINERID
            left join WORKFLOW W ON W.WORKFLOWID=DECODE(CCI.ISINSTORE,-1,C.MFGWORKFLOWID,CCI.WORKFLOWID)
            LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID=W.WORKFLOWBASEID
            left join workcenter wc on wc.workcenterid=ad.workcenterid
            LEFT JOIN ContainerStepRecord csr ON csr.containerid=ai.containerid AND csr.workflowstepid=ad.workflowstepid 
            LEFT JOIN Team t ON t.TEAMID =ad.TEAMID
              where ai.isuse=0 and ai.ApsType2=2 AND ai.ApsType =1  AND cci.ISINSTORE <>1 AND re.RESOURCEID ='{0}' and ad.Isuse=0 ";//AND csr.usecompleted<>1
        strSql += (type != "export" ? "and ('{1}' BETWEEN to_char(ad.RESSTARTTIME,'yyyy-MM-dd') AND to_char(ad.RESENDTIME,'yyyy-MM-dd'))" : "and ('{1}' BETWEEN to_char(ad.RESSTARTTIME,'yyyy-MM') AND to_char(ad.RESENDTIME,'yyyy-MM'))");
        strSql += "order by ai.containerid,ai.workflowid,ad.workflowstepid";
        DataTable dt = DatabaseHelper.Query_ReturnDatTable(string.Format(strSql, resourceID, type == "export" ? date.ToString("yyyy-MM") : date.ToString("yyyy-MM-dd")));
        foreach (DataRow row in dt.Rows)
        {
            DataTable ddt = workFlowStepMaint.GetStepResourceDatas("'" + row["specid"].ToString() + "'");
            if (!ddt.Columns.Contains("apsplandetailid")) { ddt.Columns.Add("apsplandetailid"); }
            foreach (DataRow drow in ddt.Rows)
            {
                drow["apsplandetailid"] = row["apsplandetailid"];
                drow["Description"] = drow["Description"] + "(" + drow["ResourceName"] + ")";
            }
            row["resorces"] = JsonConvert.SerializeObject(ddt);
            var RESSTARTTIME = Convert.ToDateTime(row["RESSTARTTIME"].ToString());//设备实际开始时间
            var RESENDTIME = Convert.ToDateTime(row["RESENDTIME"].ToString());//设备实际结束时间
            if (date.ToString("yyyy-MM-dd").Equals(RESSTARTTIME.ToString("yyyy-MM-dd")) && date.ToString("yyyy-MM-dd").Equals(RESENDTIME.ToString("yyyy-MM-dd")))
            {//设备开始结束跟日期是同一天
                row["dayTime"] = Math.Round(DiffHours(RESSTARTTIME, RESENDTIME), 2);
            }
            else
            {
                if (date.ToString("yyyy-MM-dd").Equals(RESSTARTTIME.ToString("yyyy-MM-dd")) && RESENDTIME > date)
                {//设备开始跟日期是同一天，结束>日期
                    row["dayTime"] = Math.Round(DiffHours(RESSTARTTIME, date.AddDays(1)), 2);
                }
                else if (date.ToString("yyyy-MM-dd").Equals(RESENDTIME.ToString("yyyy-MM-dd")) && RESSTARTTIME < date)
                {//设备结束跟日期是同一天，开始<日期
                    row["dayTime"] = Math.Round(DiffHours(date, RESENDTIME), 2);
                }
                else
                {
                    row["dayTime"] = 24;
                }

            }

        }
        if (type == "export")
        {
            dt.Columns.Remove("SPECID");
            dt.Columns.Remove("APSPLANDETAILID");
            dt.Columns.Remove("RESOURCEID");

            dt.Columns.Remove("WORKCENTERID");
            dt.Columns.Remove("TEAMID");
            dt.Columns.Remove("MAKEEMPCOUNTS");
            dt.Columns.Remove("SHIPCYCLE");
            dt.Columns.Remove("SEQUENCE");
            dt.Columns.Remove("RESORCES");
            dt.Columns.Remove("DAYTIME");

            dt.Columns["MFGORDERNAME"].ColumnName = "订单号";
            dt.Columns["CONTAINERNAME"].ColumnName = "批次号";
            dt.Columns["WORKFLOWINFO"].ColumnName = "工艺版本";
            dt.Columns["CWFNAME"].ColumnName = "当前工序";
            dt.Columns["WORKFLOWSTEPNAME"].ColumnName = "排产工序";
            dt.Columns["STEPSTARTTIME"].ColumnName = "工序开始时间";
            dt.Columns["STEPENDTIME"].ColumnName = "工序结束时间";
            dt.Columns["RESNAME"].ColumnName = "设备";
            dt.Columns["RESSTARTTIME"].ColumnName = "设备开始时间";
            dt.Columns["RESENDTIME"].ColumnName = "设备结束时间";
            //dt.Columns["DAYTIME"].ColumnName = "设备日运行时间(H)";
            dt.Columns["WORKCENTERNAME"].ColumnName = "工区";
            dt.Columns["TEAMNAME"].ColumnName = "班组";
            dt.Columns["QTY"].ColumnName = "数量";
            dt.Columns["PREPARECYCLE"].ColumnName = "准备时间（min）";
            dt.Columns["MAKECYCLE"].ColumnName = "加工时间（min）";
            dt.Columns["TRANSFERCYCLE"].ColumnName = "转运时间（H）";
            dt.Columns["COMMICYCLE"].ColumnName = "外委周期";
            byte[] bytes = uLMS_CommonFunction.DataTableExportToExcel(dt, "设备排产信息");

            var Response = HttpContext.Current.Response;
            Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}{1}.xls", HttpContext.Current.Server.UrlEncode("设备排产信息"), DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss")));
            Response.AddHeader("fileDownload", "1");
            Response.AddHeader("Set-Cookie", "fileDownload=true;path=/");
            Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
            Response.ContentType = "application/ms-excel;charset=UTF-8";
            Response.BinaryWrite(bytes);

            Response.Flush();
            Response.End();
            Response.Close();

            context.Response.Write(JsonConvert.SerializeObject(Response));
        }
        else
        {
            context.Response.Write(JsonConvert.SerializeObject(dt));
        }
    }

    /// <summary>
    /// 设备日排产数据（预排相关）
    /// </summary>
    /// <param name="context"></param>
    private void GetStepLimitedPreAps(HttpContext context)
    {
        var resourceID = context.Request["resourceID"].ToString();
        var type = context.Request["type"].ToString();
        var date = type.Equals("export") ? Convert.ToDateTime(context.Request["date"].ToString().Split(',')[0]) : Convert.ToDateTime(context.Request["date"].ToString());
        uMESProcessResult result = new uMESProcessResult();
        var strSql = @"select  cci.mfgordername,cci.containername,WB.WORKFLOWNAME||':'||W.WORKFLOWREVISION WORKFLOWINFO,cci.WORKFLOWSTEPNAME CWFNAME,ad.workflowstepname,nvl(sb.revofrcdid,ws.specid) specid,ad.apsplandetailid,to_char(ad.starttime,'yyyy-MM-dd hh24:mi:ss') stepstarttime,to_char(ad.endtime,'yyyy-MM-dd hh24:mi:ss') stependtime,
              decode(re.resourcename,null,'',re.description||'('||re.resourcename||')') RESNAME,to_char(RESSTARTTIME,'yyyy-MM-dd hh24:mi:ss')RESSTARTTIME1,(RESENDTIME-NUMTODSINTERVAL(nvl(WS.preparecycle,0), 'MINUTE')-NUMTODSINTERVAL(nvl(WS.makecycle,0)*ad.qty, 'MINUTE')) RESSTARTTIME,to_char(RESENDTIME,'yyyy-MM-dd hh24:mi:ss') RESENDTIME,
              wc.workcentername,t.teamname,ad.qty,re.resourceid,wc.workcenterid,t.teamid,WS.MAKEEMPCOUNTS,WS.PREPARECYCLE,WS.MAKECYCLE,round(WS.TRANSFERCYCLE/60,2) TRANSFERCYCLE,WS.SHIPCYCLE,WS.COMMICYCLE,ws.sequence,null resorces,null dayTime
            from ApsPlanInfopre ai 
            left join containercurrentinfo cci on cci.containerid=ai.containerid
            left join ApsPlanDetailpre ad on ad.apsplaninfoid=ai.apsplaninfoid and ad.isuse=0
            left join workflowstep ws on ws.workflowstepid=ad.workflowstepid
            left join specbase sb on sb.specbaseid=ws.specbaseid
            left join resourcedef re on re.resourceid=ad.resourceid
            LEFT JOIN CONTAINER C ON C.CONTAINERID=CCI.CONTAINERID
            left join WORKFLOW W ON W.WORKFLOWID=DECODE(CCI.ISINSTORE,-1,C.MFGWORKFLOWID,CCI.WORKFLOWID)
            LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID=W.WORKFLOWBASEID
            left join workcenter wc on wc.workcenterid=ad.workcenterid
            LEFT JOIN ContainerStepRecord csr ON csr.containerid=ai.containerid AND csr.workflowstepid=ad.workflowstepid 
            LEFT JOIN Team t ON t.TEAMID =ad.TEAMID
              where ai.isuse=0 and ai.ApsType2=2 AND ai.ApsType =1  AND cci.ISINSTORE <>1 AND re.RESOURCEID ='{0}' and ad.Isuse=0 ";//AND csr.usecompleted<>1
        //strSql += (type != "export" ? "and ('{1}' BETWEEN to_char(ad.RESSTARTTIME,'yyyy-MM-dd') AND to_char(ad.RESENDTIME,'yyyy-MM-dd'))" : "and ('{1}' BETWEEN to_char(ad.RESSTARTTIME,'yyyy-MM') AND to_char(ad.RESENDTIME,'yyyy-MM'))");
        if (type.Equals("export")) {
            strSql += string.Format(@"AND (to_char(ad.RESSTARTTIME,'yyyy-MM-dd')>='{0}' AND to_char(ad.RESENDTIME,'yyyy-MM-dd')<='{1}')", context.Request["date"].ToString().Split(',')[0], context.Request["date"].ToString().Split(',')[1]);
        } else {
            strSql += string.Format(@"and ('{0}' BETWEEN to_char(ad.RESSTARTTIME,'yyyy-MM-dd') AND to_char(ad.RESENDTIME,'yyyy-MM-dd'))",date.ToString("yyyy-MM-dd"));
        }
        strSql += "order by ai.containerid,ai.workflowid,ad.workflowstepid";
        DataTable dt = DatabaseHelper.Query_ReturnDatTable(string.Format(strSql, resourceID));
        foreach (DataRow row in dt.Rows)
        {
            DataTable ddt = workFlowStepMaint.GetStepResourceDatas("'" + row["specid"].ToString() + "'");
            if (!ddt.Columns.Contains("apsplandetailid")) { ddt.Columns.Add("apsplandetailid"); }
            foreach (DataRow drow in ddt.Rows)
            {
                drow["apsplandetailid"] = row["apsplandetailid"];
                drow["Description"] = drow["Description"] + "(" + drow["ResourceName"] + ")";
            }
            row["resorces"] = JsonConvert.SerializeObject(ddt);
            var RESSTARTTIME = Convert.ToDateTime(row["RESSTARTTIME"].ToString());//设备实际开始时间
            var RESENDTIME = Convert.ToDateTime(row["RESENDTIME"].ToString());//设备实际结束时间
            if (date.ToString("yyyy-MM-dd").Equals(RESSTARTTIME.ToString("yyyy-MM-dd")) && date.ToString("yyyy-MM-dd").Equals(RESENDTIME.ToString("yyyy-MM-dd")))
            {//设备开始结束跟日期是同一天
                row["dayTime"] = Math.Round(DiffHours(RESSTARTTIME, RESENDTIME), 2);
            }
            else
            {
                if (date.ToString("yyyy-MM-dd").Equals(RESSTARTTIME.ToString("yyyy-MM-dd")) && RESENDTIME > date)
                {//设备开始跟日期是同一天，结束>日期
                    row["dayTime"] = Math.Round(DiffHours(RESSTARTTIME, date.AddDays(1)), 2);
                }
                else if (date.ToString("yyyy-MM-dd").Equals(RESENDTIME.ToString("yyyy-MM-dd")) && RESSTARTTIME < date)
                {//设备结束跟日期是同一天，开始<日期
                    row["dayTime"] = Math.Round(DiffHours(date, RESENDTIME), 2);
                }
                else
                {
                    //row["dayTime"] = 24;
                    row["dayTime"] = Math.Round(DiffHours(RESSTARTTIME, RESENDTIME), 2);
                }

            }

        }
        if (type == "export")
        {
            dt.Columns.Remove("SPECID");
            dt.Columns.Remove("APSPLANDETAILID");
            dt.Columns.Remove("RESOURCEID");

            dt.Columns.Remove("WORKCENTERID");
            dt.Columns.Remove("TEAMID");
            dt.Columns.Remove("MAKEEMPCOUNTS");
            dt.Columns.Remove("SHIPCYCLE");
            dt.Columns.Remove("SEQUENCE");
            dt.Columns.Remove("RESORCES");
            dt.Columns.Remove("DAYTIME");

            dt.Columns["MFGORDERNAME"].ColumnName = "订单号";
            dt.Columns["CONTAINERNAME"].ColumnName = "批次号";
            dt.Columns["WORKFLOWINFO"].ColumnName = "工艺版本";
            dt.Columns["CWFNAME"].ColumnName = "当前工序";
            dt.Columns["WORKFLOWSTEPNAME"].ColumnName = "排产工序";
            dt.Columns["STEPSTARTTIME"].ColumnName = "工序开始时间";
            dt.Columns["STEPENDTIME"].ColumnName = "工序结束时间";
            dt.Columns["RESNAME"].ColumnName = "设备";
            dt.Columns["RESSTARTTIME"].ColumnName = "设备开始时间";
            dt.Columns["RESENDTIME"].ColumnName = "设备结束时间";
            //dt.Columns["DAYTIME"].ColumnName = "设备日运行时间(H)";
            dt.Columns["WORKCENTERNAME"].ColumnName = "工区";
            dt.Columns["TEAMNAME"].ColumnName = "班组";
            dt.Columns["QTY"].ColumnName = "数量";
            dt.Columns["PREPARECYCLE"].ColumnName = "准备时间（min）";
            dt.Columns["MAKECYCLE"].ColumnName = "加工时间（min）";
            dt.Columns["TRANSFERCYCLE"].ColumnName = "转运时间（H）";
            dt.Columns["COMMICYCLE"].ColumnName = "外委周期";
            byte[] bytes = uLMS_CommonFunction.DataTableExportToExcel(dt, "设备排产信息");

            var Response = HttpContext.Current.Response;
            Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}{1}.xls", HttpContext.Current.Server.UrlEncode("设备排产信息"), DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss")));
            Response.AddHeader("fileDownload", "1");
            Response.AddHeader("Set-Cookie", "fileDownload=true;path=/");
            Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
            Response.ContentType = "application/ms-excel;charset=UTF-8";
            Response.BinaryWrite(bytes);

            Response.Flush();
            Response.End();
            Response.Close();

            context.Response.Write(JsonConvert.SerializeObject(Response));
        }
        else
        {
            context.Response.Write(JsonConvert.SerializeObject(dt));
        }
    }

    private void SaveStepResourceData(HttpContext context)
    {
        var para = JsonConvert.DeserializeObject<Dictionary<string, string>>(context.Request["data"].ToString());
        var resourceid = para["RESOURCEID"];
        var apsplandetailid = para["apsplandetailid"];
        uMESProcessResult result = new uMESProcessResult();
        var updateSQL = @"update ApsPlanDetail ad set ad.resourceid='{0}' where ad.apsplandetailid='{1}'";
        result.Result = DatabaseHelper.ExecuteSql(string.Format(updateSQL, resourceid, apsplandetailid)) > 0;
        result.Message = result.Result ? "修改成功" : "修改失败";
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    private void SaveStepResourcePreData(HttpContext context)
    {
        var para = JsonConvert.DeserializeObject<Dictionary<string, string>>(context.Request["data"].ToString());
        var resourceid = para["RESOURCEID"];
        var apsplandetailid = para["apsplandetailid"];
        uMESProcessResult result = new uMESProcessResult();
        var updateSQL = @"update ApsPlanDetailPre ad set ad.resourceid='{0}' where ad.apsplandetailid='{1}'";
        result.Result = DatabaseHelper.ExecuteSql(string.Format(updateSQL, resourceid, apsplandetailid)) > 0;
        result.Message = result.Result ? "修改成功" : "修改失败";
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    private void UpdateResourceData(HttpContext context)
    {
        string workShiftId = context.Request["workShiftId"].ToString();
        string makeCalendar = context.Request["makeCalendar"].ToString();
        string isinfinite = context.Request["isinfinite"].ToString();
        string resourcename = context.Request["resourcename"].ToString();
        Dictionary<string, string> dic = new Dictionary<string, string>();
        dic.Add("workshiftid", workShiftId);//班次
        dic.Add("makecalendar", makeCalendar);//日历
        dic.Add("isinfinite", isinfinite);//是否无限能力设备
        dic.Add("resourcename", resourcename);
        dic.Add("userName", m_UserInfo.APIUserName.ToString());//
        dic.Add("passWord", m_UserInfo.APIPassword.ToString());//
        uMESProcessResult result = new uMESProcessResult();
        var operMsg = string.Empty;
        ResourceMaintBusiness resourceBusiness = new ResourceMaintBusiness();//设备类
        result.Result = resourceBusiness.ResourceMaint("update", dic, ref operMsg);
        result.Message = result.Result ? "更新成功" : "更新失败：" + operMsg;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }




    private string strSql = @"SELECT distinct w2.WORKCENTERNAME,CCI.CONTAINERID,CCI.CONTAINERNAME,CCI.PRODUCTDESCRIPTION PRODUCTDESC,CCI.PRODUCTREVISION,CCI.QTY,CCI.WORKFLOWSTEPNAME,
        DECODE(CCI.CONTAINERTYPE,2,'批量加工',3,'批量带子序号', 7,'单件加工') AS CONTAINERTYPENAME,CCI.PRODUCTNAME,CCI.PRODUCTID,
        W.WORKFLOWID,WB.WORKFLOWNAME,W.WORKFLOWREVISION,WB.WORKFLOWNAME||':'||W.WORKFLOWREVISION WORKFLOWINFO,
        TO_CHAR(M.PLANNEDSTARTDATE,'YYYY-MM-DD') MFGSTARTDATE,TO_CHAR(M.PLANNEDCOMPLETIONDATE,'YYYY-MM-DD') MFGENDDDATE,to_char(cci.ExpectMaterialDate,'yyyy-mm-dd hh24:mi:ss') ExpectMaterialDate,
        to_char(cci.materialdate,'yyyy-mm-dd hh24:mi:ss') materialdate ,TO_CHAR(M.PLANNEDSTARTDATE,'YYYY-MM-DD') REALSTARTDATE, 
        cci.togetherflag,pc.prioritycodename,cci.CriticalValue,cci.StepDuration,cci.ApsSequence,decode(cci.ApsProPre,1,'是','否') IsPrepare ,
        TO_CHAR(M.PLANNEDSTARTDATE,'YYYY-MM-DD') STARTTIME,2 DJDKSPECIAL,TO_CHAR(M.PLANNEDCOMPLETIONDATE,'YYYY-MM-DD') ENDTIME,decode(cci.ISINSTORE,-1,0,cci.workflowstepsequence-1) beginsequence
        FROM CONTAINERCURRENTINFO CCI    
        LEFT JOIN MFGORDER M ON M.MFGORDERID=CCI.MFGORDERID
        left join prioritycode pc on pc.prioritycodeid=m.priorityid
        LEFT JOIN ORDERSTATUS o ON o.orderstatusid = M.orderstatusid
        LEFT JOIN CONTAINER C ON C.CONTAINERID=CCI.CONTAINERID
        left join WORKFLOW W ON W.WORKFLOWID=DECODE(CCI.ISINSTORE,-1,C.MFGWORKFLOWID,CCI.WORKFLOWID)
        LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID=W.WORKFLOWBASEID
        LEFT JOIN WORKCENTER w2 ON w2.WORKCENTERID =CCI.WORKCENTERID 
        WHERE CCI.CONTAINERSTATUS=1 and cci.isinpool=1 and cci.isinstore != 1";

    /// <summary>
    /// 查询生产作业平衡排产数据（预排相关）
    /// </summary>
    private string strPreSql = @"SELECT distinct w2.WORKCENTERNAME,CCI.CONTAINERID,CCI.CONTAINERNAME,CCI.PRODUCTDESCRIPTION PRODUCTDESC,CCI.PRODUCTREVISION,CCI.QTY,CCI.WORKFLOWSTEPNAME,
        DECODE(CCI.CONTAINERTYPE,2,'批量加工',3,'批量带子序号', 7,'单件加工') AS CONTAINERTYPENAME,CCI.PRODUCTNAME,CCI.PRODUCTID,m.mfgordername,
        W.WORKFLOWID,WB.WORKFLOWNAME,W.WORKFLOWREVISION,WB.WORKFLOWNAME||':'||W.WORKFLOWREVISION WORKFLOWINFO,
        TO_CHAR(M.PLANNEDSTARTDATE,'YYYY-MM-DD') MFGSTARTDATE,TO_CHAR(M.PLANNEDCOMPLETIONDATE,'YYYY-MM-DD') MFGENDDDATE,to_char(cci.ExpectMaterialDate,'yyyy-mm-dd hh24:mi:ss') ExpectMaterialDate,
        to_char(cci.materialdate,'yyyy-mm-dd hh24:mi:ss') materialdate ,TO_CHAR(M.PLANNEDSTARTDATE,'YYYY-MM-DD') REALSTARTDATE, 
        cci.togetherflag,pc.prioritycodename,cci.CriticalValue,cci.StepDuration,cci.ApsSequence,decode(cci.ApsProPre,1,'是','否') IsPrepare ,
        TO_CHAR(M.PLANNEDSTARTDATE,'YYYY-MM-DD') STARTTIME,2 DJDKSPECIAL,TO_CHAR(M.PLANNEDCOMPLETIONDATE,'YYYY-MM-DD') ENDTIME,decode(cci.ISINSTORE,-1,0,cci.workflowstepsequence-1) beginsequence,
        to_char(ai.starttime,'yyyy-mm-dd hh24:mi:ss') apsstarttime,to_char(ai.endtime,'yyyy-mm-dd hh24:mi:ss') apsendtime,t.teamname,
        CASE WHEN ai.endtime > m.plannedcompletiondate THEN '是' WHEN ai.endtime IS NULL AND m.plannedstartdate + INTERVAL '35' DAY > m.plannedcompletiondate THEN '是' ELSE '否' END isoverdue
        FROM CONTAINERCURRENTINFO CCI    
        LEFT JOIN MFGORDER M ON M.MFGORDERID=CCI.MFGORDERID
        left join prioritycode pc on pc.prioritycodeid=m.priorityid
        LEFT JOIN ORDERSTATUS o ON o.orderstatusid = M.orderstatusid
        LEFT JOIN CONTAINER C ON C.CONTAINERID=CCI.CONTAINERID
        left join WORKFLOW W ON W.WORKFLOWID=DECODE(CCI.ISINSTORE,-1,C.MFGWORKFLOWID,CCI.WORKFLOWID)
        LEFT JOIN WORKFLOWBASE WB ON WB.WORKFLOWBASEID=W.WORKFLOWBASEID
        LEFT JOIN WORKCENTER w2 ON w2.WORKCENTERID =CCI.WORKCENTERID 
        left join apsplaninfopre ai ON ai.containerid = cci.containerid AND ai.isuse = 0 AND ai.apstype2 = 2 AND ai.apstype = 1
        LEFT JOIN productteaminfo pi ON pi.productname = cci.productname AND pi.isuse = 0
        LEFT JOIN team t ON t.teamid = pi.teamid
        WHERE CCI.CONTAINERSTATUS=1 and cci.isinpool=1 and cci.isinstore != 1";
}